Regex 什么是正则表达式中的非捕获组?

Regex 什么是正则表达式中的非捕获组?,regex,capturing-group,regex-group,Regex,Capturing Group,Regex Group,如何在正则表达式中使用非捕获组,即(?:),它们有什么好处??:用于对表达式进行分组,但不希望将其保存为字符串的匹配/捕获部分 例如,与IP地址匹配的内容: /(?:\d{1,3}\.){3}\d{1,3}/ 请注意,我并不关心保存前3个八位字节,但是(?:…)分组允许我缩短正则表达式,而不会产生捕获和存储匹配的开销 ?:用于对表达式进行分组,但不希望将其保存为字符串的匹配/捕获部分 例如,与IP地址匹配的内容: /(?:\d{1,3}\.){3}\d{1,3}/ 请注意,我并不关心保存前3

如何在正则表达式中使用非捕获组,即
(?:)
,它们有什么好处?

?:
用于对表达式进行分组,但不希望将其保存为字符串的匹配/捕获部分

例如,与IP地址匹配的内容:

/(?:\d{1,3}\.){3}\d{1,3}/

请注意,我并不关心保存前3个八位字节,但是
(?:…)
分组允许我缩短正则表达式,而不会产生捕获和存储匹配的开销

?:
用于对表达式进行分组,但不希望将其保存为字符串的匹配/捕获部分

例如,与IP地址匹配的内容:

/(?:\d{1,3}\.){3}\d{1,3}/

请注意,我并不关心保存前3个八位字节,但是
(?:…)
分组允许我缩短正则表达式,而不会产生捕获和存储匹配的开销

捕获的组您可以稍后在正则表达式中使用以匹配您可以在正则表达式的替换部分中使用它们。创建一个非捕获的组只是免除该组出于以下任一原因被使用

如果您试图捕获许多不同的内容,并且有些组您不想捕获,那么非捕获组是非常好的

这就是它们存在的原因。当你在学习团队的时候,要了解,他们做了很多!也有环顾组,但它们稍微复杂一点,使用不多

稍后在正则表达式中使用的示例(反向引用):

]*>.*?
[查找xml标记(不支持ns)]

([A-Z][A-Z0-9]*)
是一个捕获组(在本例中是标记名)


在正则表达式的后面部分是
\1
,这意味着它将只匹配第一组中的相同文本(
([A-Z][A-Z0-9]*)
组)(在这种情况下,它匹配的是结束标记).

捕获的组
您可以稍后在正则表达式中使用以匹配,或者您可以在正则表达式的替换部分中使用它们。创建一个非捕获的组只是免除该组出于以下任一原因被使用

如果您试图捕获许多不同的内容,并且有些组您不想捕获,那么非捕获组是非常好的

这就是它们存在的原因。当你在学习团队的时候,要了解,他们做了很多!也有环顾组,但它们稍微复杂一点,使用不多

稍后在正则表达式中使用的示例(反向引用):

]*>.*?
[查找xml标记(不支持ns)]

([A-Z][A-Z0-9]*)
是一个捕获组(在本例中是标记名)


稍后在正则表达式中是
\1
,这意味着它将只匹配第一个组中的相同文本(
([A-Z][A-Z0-9]*)
组)(在这种情况下,它匹配的是结束标记)。

它使组不捕获,这意味着由该组匹配的子字符串将不包括在捕获列表中。ruby中的一个示例说明了这一区别:

"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]

它使组不捕获,这意味着该组匹配的子字符串将不包括在捕获列表中。ruby中的一个示例说明了这一区别:

"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]

您可以使用捕获组来组织和解析表达式。非捕获组有第一个好处,但没有第二个好处的开销。例如,您仍然可以说非捕获组是可选的

假设您想匹配数字文本,但有些数字可以写为1、2、3、4、,。。。如果要捕获数字部分,而不是(可选)后缀,则可以使用非捕获组

([0-9]+)(?:st|nd|rd|th)?
console.debug(parse_url_regex.exec(url));

这将匹配表1,2,3中的数字。。。或以表格1、2、3、,。。。但是它只捕获数字部分。

您可以使用捕获组来组织和解析表达式。非捕获组有第一个好处,但没有第二个好处的开销。例如,您仍然可以说非捕获组是可选的

假设您想匹配数字文本,但有些数字可以写为1、2、3、4、,。。。如果要捕获数字部分,而不是(可选)后缀,则可以使用非捕获组

([0-9]+)(?:st|nd|rd|th)?
console.debug(parse_url_regex.exec(url));

这将匹配表1,2,3中的数字。。。或以表格1、2、3、,。。。但它只捕获数字部分。

让我试着用一个例子来解释这一点

考虑以下案文:

http://stackoverflow.com/
https://stackoverflow.com/questions/tagged/regex
现在,如果我在上面应用下面的正则表达式

(https?| ftp):/([^/\r\n]+)(/[^\r\n]*)?
。。。我将得到以下结果:

Match "http://stackoverflow.com/"
     Group 1: "http"
     Group 2: "stackoverflow.com"
     Group 3: "/"

Match "https://stackoverflow.com/questions/tagged/regex"
     Group 1: "https"
     Group 2: "stackoverflow.com"
     Group 3: "/questions/tagged/regex"
但我不关心协议——我只需要URL的主机和路径。因此,我将正则表达式更改为包含非捕获组
(?:)

(?:https?| ftp):/([^/\r\n]+)(/[^\r\n]*)?
现在,我的结果如下所示:

Match "http://stackoverflow.com/"
     Group 1: "stackoverflow.com"
     Group 2: "/"

Match "https://stackoverflow.com/questions/tagged/regex"
     Group 1: "stackoverflow.com"
     Group 2: "/questions/tagged/regex"
看到了吗?第一组尚未捕获。解析器使用它来匹配文本,但在最终结果中忽略它


编辑: 按照要求,让我也试着解释一下小组

嗯,团体有很多目的。它们可以帮助您从更大的匹配(也可以命名)中提取准确信息,让您重新匹配先前匹配的组,并可用于替换。我们来举几个例子,好吗

假设您有某种XML或HTML(请注意,作为一个示例,这很好)。您希望解析标记,因此可以执行类似的操作(我添加了空格以便于理解):


\[^让我试着用一个例子来解释这一点

考虑以下案文:

http://stackoverflow.com/
https:/
var url = "http://www.ora.com:80/goodparts?q#fragment";
console.debug(parse_url_regex.exec(url));
"Peace".match(/(\w)(\w)(\w)/)
["Pea", "P", "e", "a", index: 0, input: "Peace", groups: undefined]
"Peace".match(/(?:\w)(\w)(\w)/)
["Pea", "e", "a", index: 0, input: "Peace", groups: undefined]
([0-9]+)(?:January|February)?