如何在正则表达式中使用非捕获组,即(?:),它们有什么好处?
当前回答
让我举个例子:
Regex代码:(?:animal)(?:=)(\w+)(,)\1\2
搜索字符串:
第1行-动物=猫、狗、猫、老虎、狗
第2行-动物=猫、猫、狗、狗、老虎
第3行-动物=狗、狗、猫、猫、老虎
(?:动物)-->未捕获组1
(?:=)-->未捕获组2
(\w+)-->捕获的组1
(,)-->捕获的组2
\1-->捕获组1的结果,即第1行是猫,第2行是猫、第3行是狗。
\2-->捕获组2的结果,即逗号(,)
因此,在这段代码中,通过给出“1”和“2”,我们在代码后面分别回忆或重复捕获的组1和组2的结果。
根据代码的顺序,(?:动物)应为第1组,(?=)应为2组,并继续。。
但通过给出?:我们使匹配组不被捕获(在匹配组中不计数,因此分组编号从第一个捕获的组开始,而不是未捕获的组),这样以后就不能在代码中调用匹配组(?:动物)结果的重复。
希望这能解释非捕获组的使用。
其他回答
我想我会给你答案。在未检查匹配是否成功的情况下,不要使用捕获变量。
除非匹配成功,否则捕获变量$1等无效,并且它们也不会被清除。
#!/usr/bin/perl
use warnings;
use strict;
$_ = "bronto saurus burger";
if (/(?:bronto)? saurus (steak|burger)/)
{
print "Fred wants a $1";
}
else
{
print "Fred dont wants a $1 $2";
}
在上面的示例中,为了避免在$1中捕获bronto,使用了(?:)。
如果模式匹配,则$1被捕获为下一个分组模式。
因此,输出如下:
Fred wants a burger
如果不希望保存匹配项,则此选项很有用。
它使组不捕获,这意味着该组匹配的子字符串将不包含在捕获列表中。ruby中的一个示例说明了区别:
"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]
打开您的Google Chrome devTools,然后单击Console选项卡:并键入以下内容:
"Peace".match(/(\w)(\w)(\w)/)
运行它,您将看到:
["Pea", "P", "e", "a", index: 0, input: "Peace", groups: undefined]
JavaScript RegExp引擎捕获三个组,索引为1、2、3的项。现在使用非捕获标记来查看结果。
"Peace".match(/(?:\w)(\w)(\w)/)
结果是:
["Pea", "e", "a", index: 0, input: "Peace", groups: undefined]
这是显而易见的非捕获组。
在复杂的正则表达式中,可能会出现这样的情况:您希望使用大量的组,其中一些组用于重复匹配,另一些组用于提供反向引用。默认情况下,匹配每个组的文本将加载到backreference数组中。如果我们有很多组,并且只需要能够从backreference数组中引用其中的一些组,我们可以重写此默认行为,告诉正则表达式某些组只用于重复处理,不需要捕获并存储在backreference阵列中。
我不能评论最上面的答案来这样说:我想补充一个明确的观点,这只是在最上面的回答中暗示的:
非捕获组(?…)不会从原始完全匹配中删除任何字符,它只会对程序员进行可视化的正则表达式重组。
要访问正则表达式的特定部分而不定义外来字符,您将始终需要使用.group(<index>)