in reply to Regex: first match that is not enclosed in parenthesis
If, as your example suggests, you do not need arbitrarily nested parens, the following will work:
my $str = "1*(2+3)*(3+4)+5*(6+7)"; $str =~ /(?: \( .+? \) | [^+()] )+ (\+ .*)/x; say "Match: $1";
Outputs:
Match: +5*(6+7)However, if you need to handle a string where a + sign immediately follows a closing paren, such as ((3+4)+2), you can use recursive regexps:
$str = "1*(2+3)*(7+(3+4)+2)+5*(6+7)"; $str =~ /( \( (?: [^()]++ | (?1) )* \) | [^+()] )+ (\+ .*)/x; say "Match: $2";
Outputs:
Match: +5*(6+7)Update: Here's a more descriptive version of that last regexp:
/( # Capture group 1 \( # Opening paren (?: # Non-capture group [^()]++ # Match non-brackets, no backtracking | (?1) # Recurse to group 1. (?R) works, too. )* # Zero or more times \) # Closing paren | [^+()] # Anything outside of parens not a + or paren )+ # Not *, assuming you only want addition, not # +positive integers at beginning of string (\+ .*) # Plus sign, and remainder of string /x;
|
|---|