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

Dear Monks,

If I use the construct (?(condition)yes-pattern) in a regex, and the condition is the execute-perl-code construct (?{1}), i.e. the condition is always true, the output is as expected:

my $str = 'bxAybz'; while ( $str =~ /(?(?{1})(b[xyz]))/g ) { say 'yes'; say $1; } --output:-- yes bx yes bz

But when I use the condition (?{pos() % 2 == 0}), I expect the same output, but I don't get it:

my $str = 'bxAybz'; while ( $str =~ /(?(?{pos() % 2 == 0})(b[xyz]))/g ) { say 'yes'; say $1; } --output:-- yes bx yes Use of uninitialized value $1 in say at 2.pl line 9. yes bz

Three matches?

Also, I notice the x modifier doesn't work with a conditional regex:

my $str = 'bxAybz'; while ( $str =~ / (? (?{1}) (b[xyz]) ) /gx ) { say 'yes'; say $1; } --output:-- Sequence (? ...) not recognized in regex; marked by <-- HERE in m/ (? <-- HERE (?{1}) (b[xyz]) ) / at 2.pl line 12.
That feels like a bug.

Replies are listed 'Best First'.
Re: Conditional regex
by Anonymous Monk on Feb 17, 2013 at 18:35 UTC

    But when I use the condition (?{pos() % 2 == 0}), I expect the same output, but I don't get it:

    Employ Basic debugging checklist or

    add use re 'debug'; to see what the regex engine is doing, and why your match fails

    then adjust your pos invocation

    Also, your code wont run as is -- come on :) use feature or whatever

    Also, I notice the x modifier doesn't work with a conditional pattern:

    It does , you just can't have space in condition, it has to be (?(?{, otherwise you couldn't distinguish between some constructs

      It does , you just can't have space ... otherwise you couldn't distinguish between some constructs

      Further to Anonymonk's point: This is common. Eliminating the extraneous space around  ? in the example below allows this pedestrian regex to compile and work as expected.

      >perl -wMstrict -le "print 'match' if 'xxx' =~ m{ ( ? : x ) }xms; " Sequence (? ...) not recognized in regex...

      perlre says

      (?(condition)yes-pattern|no-pattern)

      (?(condition)yes-pattern)

      Conditional expression. Matches yes-pattern if condition yields a true value, matches no-pattern otherwise. A missing pattern always matches.