in reply to Re^2: Regex conditional match if previous match in same expression is true?
in thread Regex conditional match if previous match in same expression is true?

Other posters were correct when they changed things from using the {min,max} quantifier notation on the inside of the capture buffer to using the '?' quantifier on the outside. There is a crucial difference between "empty but matching" and "not matching", and {0,1} doesnt have the same behaviour as '?' even though they are functionally equivelent. (This may be construed as a bug :-) Alternatively you can do what i do below, which is to put the capture inside of an alternation.

Anyway, the following uses the conditional pattern with lookahead/lookbehind to match as you requested. You can play around with it to easily forbid {{hello}}, as the current code allows it.

use strict; use warnings; for ( 'oh {hello} there', 'oh {hello there', 'oh hello there', 'oh hello} there', 'of {{hello}} there', ) { if ( $_ =~ / (?: ( \{ ) # capture a '{' | # or (?<! \{ ) # not preceded by a '{' ) hello # .. followed by 'hello' (?(1) # if (defined $1) \} # match an '}' | # else (?! \} ) # not followed by a '}' ) # /x) { print "YEP : $_ : ", defined $1 ? "'$1'" : 'undef', " - $&\n"; } else { print "NOPE: $_\n"; } } __END__ YEP : oh {hello} there : '{' - {hello} NOPE: oh {hello there YEP : oh hello there : undef - hello NOPE: oh hello} there YEP : of {{hello}} there : '{' - {hello}

Also I changed your diagnostic code, you were using $1 even when the match failed, which meant you were getting the wrong thing.

---
$world=~s/war/peace/g

  • Comment on Re^3: Regex conditional match if previous match in same expression is true?
  • Download Code

Replies are listed 'Best First'.
Re^4: Regex conditional match if previous match in same expression is true?
by radiantmatrix (Parson) on Apr 10, 2007 at 15:59 UTC

    Hm, I hadn't thought of using alternation in this way. Most helpful, thank you! My comments to ikegami apply to your post as well.

    What do you mean by I was "getting the wrong thing"? I mean, I was attempting to print an undef value, which threw warnings... but was I really getting inaccurate results that way? Mind clarifying a little?

    <radiant.matrix>
    Ramblings and references
    The Code that can be seen is not the true Code
    I haven't found a problem yet that can't be solved by a well-placed trebuchet

      $1 is a dynamically scoped variable that contains details from the last successful match in the current scope. It is NOT set to undef after a failed match.

      Regarding your comments to ikegami, they dont seem so relevent here. I didnt use an eval operator, as for how to accomplish the goal with the conditional pattern and not alternation, well ive already done that havent I? If you mean regarding MRE, id say just work through the book. There is a way of thinking about things that makes regexes easy to understand, and there is a way that will lead to confusion. I dont recall specifically anything that gives a particularly good discussion of the conditional pattern. I have never encountered one in live code.

      ---
      $world=~s/war/peace/g