如何在正则表达式中使用非捕获组,即(?:),它们有什么好处?
当前回答
在复杂的正则表达式中,可能会出现这样的情况:您希望使用大量的组,其中一些组用于重复匹配,另一些组用于提供反向引用。默认情况下,匹配每个组的文本将加载到backreference数组中。如果我们有很多组,并且只需要能够从backreference数组中引用其中的一些组,我们可以重写此默认行为,告诉正则表达式某些组只用于重复处理,不需要捕获并存储在backreference阵列中。
其他回答
tl;dr非捕获组,顾名思义,是正则表达式中不希望包含在匹配中的部分,以及?:是一种将组定义为非捕获的方法。
假设你有一个电子邮件地址example@example.com.以下正则表达式将创建两个组,id部分和@example.com部分。(\p{Alpha}*[a-z])(@example.com)。为了简单起见,我们提取了包括@字符在内的整个域名。
现在让我们假设,您只需要地址的id部分。您要做的是获取匹配结果的第一个组,在正则表达式中用()包围,这样做的方法是使用非捕获组语法,即?:。因此,正则表达式(\p{Alpha}*[a-z])(?:@example.com)将只返回电子邮件的id部分。
让我举个例子:
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组,并继续。。
但通过给出?:我们使匹配组不被捕获(在匹配组中不计数,因此分组编号从第一个捕获的组开始,而不是未捕获的组),这样以后就不能在代码中调用匹配组(?:动物)结果的重复。
希望这能解释非捕获组的使用。
打开您的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]
这是显而易见的非捕获组。
您可以使用捕获组来组织和分析表达式。非捕获组具有第一个好处,但没有第二个好处的开销。例如,您仍然可以说非捕获组是可选的。
假设你想匹配数字文本,但有些数字可以写成1、2、3、4,。。。如果要捕获数字部分,而不是(可选)后缀,则可以使用非捕获组。
([0-9]+)(?:st|nd|rd|th)?
这将匹配形式1、2、3…或形式1、第2、第3…的数字,。。。但它将只捕获数字部分。
它使组不捕获,这意味着该组匹配的子字符串将不包含在捕获列表中。ruby中的一个示例说明了区别:
"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]
推荐文章
- 如何从JavaScript中使用正则表达式的字符串中剥离所有标点符号?
- 正则表达式中的单词边界是什么?
- 如何将一个标题转换为jQuery的URL段塞?
- Javascript和regex:分割字符串并保留分隔符
- (grep)正则表达式匹配非ascii字符?
- 如何在保持原始字符串的同时对字符串执行Perl替换?
- 创建正则表达式匹配数组
- *的区别是什么?和。*正则表达式?
- 如何将“camelCase”转换为“Camel Case”?
- 在Java中使用正则表达式提取值
- Java中的正则表达式命名组
- 使用正则表达式搜索和替换Visual Studio代码
- 使用split("|")按管道符号拆分Java字符串
- 替换字符串中第一次出现的模式
- “\d”在正则表达式中是数字吗?