我几年前写的脚本中有一个正则表达式。
我知道这个正则表达式的作用(寻找高于80%的百分比),但我不记得它的含义/原理。我看到使用了三元运算符,并且最后一个封闭的括号匹配,但是例如,我不知道的含义是??:
qr/^(\d+)%$(??{$^N>= 80 ? '':'^'})/
Run Code Online (Sandbox Code Playgroud)
谁能为我解释这个正则表达式?
Rob*_*sch 10
在我回答之前,我想指出,(??...)如果您不完全了解嵌入式Perl代码格式的含义,则可能会充满错误。我已经编写了perl regexen已有20多年了,我的自然趋势是总是编写这样的“用例”作为regex结果的过滤器,而不是将perl代码直接嵌入到regex中。你被警告了。
好吧,让我们分开这个正则表达式:
^ # 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
Run Code Online (Sandbox Code Playgroud)
其中$^N引用最新的闭合匹配对的值,(??{ ... })零宽度子句将执行它包装的perl代码,将其返回的值转换为新的正则表达式,并将其添加到原始模式中。
因此,在此示例中,我们匹配一个或多个数字,后跟一个百分号字符。然后,如果捕获的值大于或等于80,则针对文本评估一个空模式(有效地使整个模式匹配,返回捕获的值),否则,评估无法执行的^(文本开始)模式在字符串末尾匹配,有效地什么也不返回。
(请注意,通过将/ x修饰符添加到Perl regex中,您可以将注释直接嵌入到模式中,该模式也将忽略嵌入的空格。我发现这是记录复杂的regexen的好方法。)
$(??{code})执行code,然后将结果替换为正则表达式。在这种情况下,$^N在其中替换为与最新捕获组匹配的任何对象(\d+)。然后再次匹配具有该替换的正则表达式。
因此,如果字符串以数字开头,后跟%,则^(\d+)%匹配该数字。然后执行$^N >= 80 ? '' : '^',替换$^N为数字。如果数字至少为80,则regexp变为^(\d+)%,并且整个匹配成功。但是如果数量少于80,则变为^(\d+)%^。由于第二个^在字符串中间无法匹配,因此正则表达式不再匹配。
因此,此正则表达式匹配以百分比开头(至少为80)的字符串。