Perl RegEx:“ ??”的含义

tai*_*iko 5 regex perl

我几年前写的脚本中有一个正则表达式。

我知道这个正则表达式的作用(寻找高于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的好方法。)

  • 哦,应该注意,捕获组将匹配大于100%的值,这可能不是预期的。将捕获组更改为“ 100 | \ d {1,2}”,以将值从0匹配到100。 (3认同)

Bar*_*mar 7

$(??{code})执行code,然后将结果替换为正则表达式。在这种情况下,$^N在其中替换为与最新捕获组匹配的任何对象(\d+)。然后再次匹配具有该替换的正则表达式。

因此,如果字符串以数字开头,后跟%,则^(\d+)%匹配该数字。然后执行$^N >= 80 ? '' : '^',替换$^N为数字。如果数字至少为80,则regexp变为^(\d+)%,并且整个匹配成功。但是如果数量少于80,则变为^(\d+)%^。由于第二个^在字符串中间无法匹配,因此正则表达式不再匹配。

因此,此正则表达式匹配以百分比开头(至少为80)的字符串。