http://www.perlmonks.org?node_id=1225308

rsFalse has asked for the wisdom of the Perl Monks concerning the following question:

Hello.

I would like to learn more about Special Backtracking Control Verbs (PRUNE, SKIP, and others). Perldocs: Special Backtracking Control Verbs .
Where can I find good uses and more examples about them?
I was searching for tutorials and have found one in the RexEgg (Also here is described differences in behaviour: DWIM vs optimized, and called as bugs).
Can you suggest more tutorials, or give examples of codes, where these control verbs were applied nicely?

Replies are listed 'Best First'.
Re: Where can I find more examples of use of Special Backtracking Control Verbs?
by Eily (Monsignor) on Nov 06, 2018 at 17:14 UTC

    I'd suggest Super Search. Which will basically show that AnomalousMonk is the local expert on the subject :P. After a quick browse, I have extracted two bits of interresting (to me) information. First (*SKIP) and (*FAIL) can be used for something that quacks like variable length look behind assertions, as discussed here. Second, (*FAIL) is identical to (?!), and one is actually compiled to the other.

    I find this interesting because I have actually never used any of the control verbs - I remember having a vague understanding of what they do, and how to use them, but not why I would need them - while I have used look-around assertions (mostly look ahead) on several occasions and have a more intuitive understanding of them.

    On the "variable length look behind assertion" case though, a far simpler solution has been made available with \K. This may be one reason why (*SKIP) and (*FAIL) aren't very common, but might also be another gateway to understanding what they do

      \K is the basis for a variable length positive look behind assertion. The case discussed here implements a variable length negative look behind assertion, which in Perl must always be emulated in some way (ATM).


      Give a man a fish:  <%-{-{-{-<

        Ahem, yes. I failed to see that. Thanks pointing that out.

        On a completly far-fetched note, now that I think I understand the (*SKIP)(*FAIL) pattern, it seems to me that it only covers the subset of negative look behind assertions that do not come after any character has been matched. For example: /^(.{5})+(?<!ab*c)d/ (which is the same as matching /d(?!cb*a)(.{5})+$/ on the reverse string) can't be rewritten using the (*SKIP)(*FAIL) pattern (AFAICT). I'm sure this is a problem people stumble upon all the time :P

Re: Where can I find more examples of use of Special Backtracking Control Verbs?
by rsFalse (Chaplain) on Nov 06, 2018 at 19:33 UTC
    I usually use '(*FAIL)' with '(?{})' to generate all possible substrings of the string, or in similar cases. E.g.
    my $string = <>; my %substrings; $string =~ /(.+)(?{ $substrings{ $1 } = 1 })(*FAIL)/;
    E.g. to calculate some statistics:
    / (\b\d+\b) .*? (\b\d+\b) (?{ $count += $1 > $2 }) (*FAIL) /x;
    But have no experience of using PRUNE, SKIP and others :)
      Also once I used '(?{})' with '(*FAIL)' simply for traversing all characters of the string.
      /.(?{ do_smth( $& ) })(*FAIL)/ for @lines;
      This part:
      /.(?{ do_smth( $& ) })(*FAIL)/
      is similar to:
      do_smth( $& ) while /./g;
      , but it can not(?) be combined with 'for' into one short expression like:
      do_smth( $& ) while /./g for @lines; # syntax error
      Instead I should write:
      do{ do_smth( $& ) while /./g } for @lines;
      Another variant here was to concatenate all lines: my $concatenated_lines = join $some_concatenator, @lines. And then simply match. But imagine if the regex is more complex and can accidentally match a concatenator as well.
      And another alternative here was to use eval within non-destructive substitution:
      s/./ do_smth( $& ) /ger for @lines;
      Note modifiers: e - for eval, and r - for non-destructiveness.
      But imagine do_smth function returning long strings (e.g. ( ( ord $& ) % 2 ? $odds : $evens ) .= $&) and it could possibly(?) slow down process.
Re: Where can I find more examples of use of Special Backtracking Control Verbs?
by choroba (Cardinal) on Nov 07, 2018 at 12:42 UTC
    I used the verbs once in a programming contest: Regular Expresso 2
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,