Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl RegEx: meaning of "??"

Tags:

regex

perl

I have a regular expression in my script which I wrote years ago.

I know what this regex does (looking for percentages higher than 80%), but I don't remember its meaning/principles. I see the ternary operator is used, and also last closed parenthesis match, but what I don't know for example is the meaning of ??:

qr/^(\d+)%$(??{$^N>= 80 ? '':'^'})/

Can anybody explain this regex for me?

like image 332
taiko Avatar asked Dec 06 '22 10:12

taiko


1 Answers

Before I answer, I'd like to point out that use of the embedded perl code form (??...) can be fraught with errors if you do not fully understand its implications. I've written perl regexen for more than twenty years and my natural tendency is to always code a "use case" like this as a filter to the result of the regex rather than embed perl code directly into the regex. You have been warned.

Ok, let's pick this regex apart:

^           # start of text

(           # begin capture group
  \d+         # one or more digits 0-9
)           # end of capture group

%           # literal percent sign character

$           # end of text

(??{        # start embedded perl code

  $^N >= 80   # if last closed match group($^N) is greater than or equal to 80
    ? ''        # then return empty pattern ('') 
    : '^'       # else return start of text (^) pattern

})          # end embedded perl code

where $^N references the value of the most recent closed match pair and the (??{ ... }) zero-width clause will execute the perl code it wraps, converting the value it returns into a new regex that will be added to the original pattern.

So, in this example, we match one or more digits followed immediately by a percent sign character. Then, if the captured value is greater than or equal to 80, evaluate an empty pattern against the text (effectively allowing the overall pattern to match, returning the captured value), or if not, evaluate the ^ (start of text) pattern which cannot match at the end of the string, effectively returning nothing.

(Note that by added the /x modifier to your Perl regex, you can embed comments directly into the pattern which will also ignore embedded whitespace. I've found this to be a great way to document complicated regexen.)

like image 170
Rob Raisch Avatar answered Dec 21 '22 00:12

Rob Raisch