什么是非捕获组?(?)做什么?

时间:2022-05-29 12:15:22

How ?: is used and what it's good for?

如何使用?它的好处是什么?

12 个解决方案

#1


1733  

Let me try to explain this with an example.

让我用一个例子来解释一下。

Consider the following text:

考虑以下文本:

https://*.com/
https://*.com/questions/tagged/regex

Now, if I apply the regex below over it...

现在,如果我把正则表达式应用到下面。

(https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

... I would get the following result:

…我将得到以下结果:

Match "https://*.com/"
     Group 1: "http"
     Group 2: "*.com"
     Group 3: "/"

Match "https://*.com/questions/tagged/regex"
     Group 1: "http"
     Group 2: "*.com"
     Group 3: "/questions/tagged/regex"

But I don't care about the protocol -- I just want the host and path of the URL. So, I change the regex to include the non-capturing group (?:).

但我不关心协议——我只想要URL的主机和路径。因此,我将regex更改为包含非捕获组(?:)。

(?:https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

Now, my result looks like this:

现在,我的结果是这样的:

Match "https://*.com/"
     Group 1: "*.com"
     Group 2: "/"

Match "https://*.com/questions/tagged/regex"
     Group 1: "*.com"
     Group 2: "/questions/tagged/regex"

See? The first group has not been captured. The parser uses it to match the text, but ignores it later, in the final result.

看到了吗?第一组没有被抓获。解析器使用它来匹配文本,但是在最后的结果中会忽略它。


EDIT:

As requested, let me try to explain groups too.

按照要求,让我试着解释一下小组。

Well, groups serve many purposes. They can help you to extract exact information from a bigger match (which can also be named), they let you rematch a previous matched group, and can be used for substitutions. Let's try some examples, shall we?

群体服务于许多目的。它们可以帮助您从更大的匹配(也可以命名)中提取准确的信息,它们让您重新匹配上一个匹配的组,并且可以用于替换。让我们来试几个例子,好吗?

Ok, imagine you have some kind of XML or HTML (be aware that regex may not be the best tool for the job, but it is nice as an example). You want to parse the tags, so you could do something like this (I have added spaces to make it easier to understand):

好的,假设您有某种XML或HTML(请注意,regex可能不是工作的最佳工具,但它是很好的示例)。您想要解析这些标记,所以您可以这样做(我添加了空格以使其更易于理解):

   \<(?<TAG>.+?)\> [^<]*? \</\k<TAG>\>
or
   \<(.+?)\> [^<]*? \</\1\>

The first regex has a named group (TAG), while the second one uses a common group. Both regexes do the same thing: they use the value from the first group (the name of the tag) to match the closing tag. The difference is that the first one uses the name to match the value, and the second one uses the group index (which starts at 1).

第一个regex有一个命名组(TAG),第二个regex使用一个公共组。两个regex都做同样的事情:它们使用第一个组(标记的名称)的值来匹配结束标记。不同之处在于,第一个使用名称来匹配值,第二个使用组索引(从1开始)。

Let's try some substitutions now. Consider the following text:

现在我们来做一些替换。考虑以下文本:

Lorem ipsum dolor sit amet consectetuer feugiat fames malesuada pretium egestas.

Now, let's use the this dumb regex over it:

现在,让我们用这个愚蠢的正则表达式:

\b(\S)(\S)(\S)(\S*)\b

This regex matches words with at least 3 characters, and uses groups to separate the first three letters. The result is this:

这个regex匹配至少3个字符的单词,并使用组分隔前三个字母。结果是这样的:

Match "Lorem"
     Group 1: "L"
     Group 2: "o"
     Group 3: "r"
     Group 4: "em"
Match "ipsum"
     Group 1: "i"
     Group 2: "p"
     Group 3: "s"
     Group 4: "um"
...

Match "consectetuer"
     Group 1: "c"
     Group 2: "o"
     Group 3: "n"
     Group 4: "sectetuer"
...

So, if we apply the substitution string...

如果我们应用替换字符串…

$1_$3$2_$4

... over it, we are trying to use the first group, add an underscore, use the third group, then the second group, add another underscore, and then the fourth group. The resulting string would be like the one below.

…在上面,我们尝试使用第一组,添加下划线,使用第三组,然后第二组,再加一个下划线,然后第四组。得到的字符串将与下面的字符串类似。

L_ro_em i_sp_um d_lo_or s_ti_ a_em_t c_no_sectetuer f_ue_giat f_ma_es m_la_esuada p_er_tium e_eg_stas.

You can use named groups for substitutions too, using ${name}.

您也可以使用命名组进行替换,使用${name}。

To play around with regexes, I recommend http://regex101.com/, which offers a good amount of details on how the regex works; it also offers a few regex engines to choose from.

为了与regex进行交互,我推荐http://regex101.com/,它提供了大量关于regex工作的详细信息;它还提供了一些regex引擎可供选择。

#2


128  

You can use capturing groups to organize and parse an expression. A non-capturing group has the first benefit, but doesn't have the overhead of the second. You can still say a non-capturing group is optional, for example.

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

Say you want to match numeric text, but some numbers could be written as 1st, 2nd, 3rd, 4th,... If you want to capture the numeric part, but not the (optional) suffix you can use a non-capturing group.

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

([0-9]+)(?:st|nd|rd|th)?

That will match numbers in the form 1, 2, 3... or in the form 1st, 2nd, 3rd,... but it will only capture the numeric part.

这将匹配表格1、2、3…或者在表格1,2,3,…但它只会捕获数值部分。

#3


83  

?: is used when you want to group an expression, but you do not want to save it as a matched/captured portion of the string.

?:当您想要对表达式进行分组时,但不希望将其保存为字符串的匹配/捕获部分。

An example would be something to match an IP address:

一个例子可以匹配一个IP地址:

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

Note that I don't care about saving the first 3 octets, but the (?:...) grouping allows me to shorten the regex without incurring the overhead of capturing and storing a match.

注意,我不关心保存前3个octets,但是(?:…)分组使我可以缩短regex,而不需要捕获和存储匹配的开销。

#4


25  

It makes the group non-capturing, which means that the substring matched by that group will not be included in the list of captures. An example in ruby to illustrate the difference:

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

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

#5


12  

Groups that capture you can use later on in the regex to match OR you can use them in the replacement part of the regex. Making a non-capturing group simply exempts that group from being used for either of these reasons.

捕获您的组可以在regex中稍后使用,或者您可以在regex的替换部分使用它们。使一个非捕获组简单地使该组免于被用于上述任何一个原因。

Non-capturing groups are great if you are trying to capture many different things and there are some groups you don't want to capture.

如果你试图捕捉许多不同的东西,并且有一些你不想捕捉的群体,那么非捕捉组是非常棒的。

Thats pretty much the reason they exist. While you are learning about groups, learn about Atomic Groups, they do a lot! There is also lookaround groups but they are a little more complex and not used so much.

这就是它们存在的原因。当你学习有关群体的知识时,学习原子组,他们做了很多!也有观察组,但他们比较复杂,不怎么使用。

Example of using later on in the regex (backreference):

稍后在regex中使用的示例(backreference):

<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1> [ Finds an xml tag (without ns support) ]

<([a - z][A-Z0-9]*)\[^ >]* b >。* ? [找到一个xml标签(没有ns支持)]

([A-Z][A-Z0-9]*) is a capturing group (in this case it is the tagname)

(a - z) [a - z0 -9]*)是一个捕获组(在本例中它是tagname)

Later on in the regex is \1 which means it will only match the same text that was in the first group (the ([A-Z][A-Z0-9]*) group) (in this case it is matching the end tag).

稍后在regex中是\1,这意味着它将只匹配第一个组中的相同文本(([A-Z][A-Z0-9]*)组)(在本例中它是匹配结束标记)。

#6


12  

HISTORICAL MOTIVATION: The existence of non-capturing groups can be explained with the use of parenthesis. Consider the expressions (a|b)c and a|bc, due to priority of concatenation over |, these expressions represent two different languages ({ac, bc} and {a, bc} respectively). However, the parenthesis are also used as a matching group (as explained by the other answers...).

历史动机:非捕获组的存在可以用括号来解释。考虑到表达式(|b)c和|bc,由于在|上的连接优先级,这些表达式分别表示两种不同的语言({ac, bc}和{a, bc})。然而,括号也用作匹配组(如其他答案所解释…)。

When you want to have parenthesis but not capture the subexpression you use NON-CAPTURING GROUPS. In the example, (?:a|b)c

当您想要有括号但不捕获子表达式时,您可以使用非捕获组。在这个例子中,(?:| b)c

#7


6  

Well I am a JavaScript developer and will try to explain its significance pertaining to JavaScript.

我是一个JavaScript开发人员,将尝试解释它与JavaScript相关的意义。

Consider a scenario where you want to match cat is animal when you would like match cat and animal and both should have a is in between them.

考虑这样一个场景:当你想要匹配猫和动物时,你想要匹配猫是动物,两者之间应该有一个。

 // this will ignore "is" as that's is what we want
"cat is animal".match(/(cat)(?: is )(animal)/) ;
result ["cat is animal", "cat", "animal"]

 // using lookahead pattern it will match only "cat" we can
 // use lookahead but the problem is we can not give anything
 // at the back of lookahead pattern
"cat is animal".match(/cat(?= is animal)/) ;
result ["cat"]

 //so I gave another grouping parenthesis for animal
 // in lookahead pattern to match animal as well
"cat is animal".match(/(cat)(?= is (animal))/) ;
result ["cat", "cat", "animal"]

 // we got extra cat in above example so removing another grouping
"cat is animal".match(/cat(?= is (animal))/) ;
result ["cat", "animal"]

#8


6  

Let me try this with an example :-

让我用一个例子来试试:-。

Regex Code :- (?:animal)(?:=)(\w+)(,)\1\2

正则表达式代码:-(?:动物)(:=)(\ w +)1(,)\ \ 2

Search String :-

搜索字符串:

Line 1 - animal=cat,dog,cat,tiger,dog

1号线-动物=猫、狗、猫、虎、狗

Line 2 - animal=cat,cat,dog,dog,tiger

行2 -动物=猫,猫,狗,狗,老虎

Line 3 - animal=dog,dog,cat,cat,tiger

3号线-动物=狗,狗,猫,猫,老虎

(?:animal) --> Non-Captured Group 1

(动物)->未捕获的第一组。

(?:=)--> Non-Captured Group 2

(? =)——>未捕获组2

(\w+)--> Captured Group 1

(\ w +)- - >组1

(,)--> Captured Group 2

(,)- - >组2捕获

\1 --> result of captured group 1 i.e In Line 1 is cat,In Line 2 is cat,In Line 3 is dog.

\1——捕获组1的>结果。e在第1行是cat,第2行是cat,第3行是dog。

\2 -->result of captured group 2 i.e comma(,)

\2——捕获组2的>结果。e逗号(,)

So in this code by giving \1 and \2 we recall or repeat the result of captured group 1 and 2 respectively later in the code.

因此,在这段代码中,我们回忆或重复了在代码中稍后捕获的第1组和第2组的结果。

As per the order of code (?:animal) should be group 1 and (?:=) should be group 2 and continues..

按照代码的顺序(?:动物)应该是第1组,并且(? =)应该是第2组,并且继续。

but by giving the ?: we make the match-group non captured(which do not count off in matched group, so the grouping number starts from the first captured group and not the non captured), so that the repetition of the result of match-group (?:animal) can't be called later in code.

但是通过给予?:我们使match-group不被捕获(在匹配的组中没有计数,所以分组编号从第一个被捕获的组开始,而不是未捕获的),这样就不能在代码中调用match-group (?:animal)的结果。

Hope this explains the use of non capturing group.

希望这可以解释为什么使用非捕获组。

enter image description here

在这里输入图像描述

#9


5  

In complex regular expressions you may have the situation arise where you wish to use a large number of groups some of which are there for repetition matching and some of which are there to provide back references. By default the text matching each group is loaded into the backreference array. Where we have lots of groups and only need to be able to reference some of them from the backreference array we can override this default behaviour to tell the regular expression that certain groups are there only for repetition handling and do not need to be captured and stored in the backreference array.

在复杂的正则表达式中,您可能会出现这样的情况:您希望使用大量的组,其中一些组用于重复匹配,其中一些用于提供反向引用。默认情况下,将每个组匹配的文本加载到backreference数组中。我们有很多团体,只需要能够从backreference数组引用其中一些我们能够覆盖这个默认的行为告诉某些群体的正则表达式重复处理,不需要捕获并存储在backreference数组。

#10


2  

One interesting thing that I came across is the fact that you can have a capturing group inside a non-capturing group. Have a look at below regex for matching web urls:

我遇到的一个有趣的事情是,你可以在一个非捕获组中拥有一个捕获组。在regex下面查看匹配的web url:

var parse_url_regex = /^(?:([A-Za-z]+):)(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

Input url string:

输入url字符串:

var url = "http://www.ora.com:80/goodparts?q#fragment";

The first group in my regex (?:([A-Za-z]+):) is a non-capturing group which matches the protocol scheme and colon : character i.e. http: but when I was running below code, I was seeing the 1st index of the returned array was containing the string http when I was thinking that http and colon : both will not get reported as they are inside a non-capturing group.

第一组在我的正则表达式(?:([A-Za-z]+):)是一群无匹配的协议方案和结肠癌:性格即http:但我运行下面的代码的时候,我看到第一索引返回的数组是包含字符串http认为http和结肠的时候:不会得到报告,因为他们都是在一个无组。

console.debug(parse_url_regex.exec(url));

什么是非捕获组?(?)做什么?

I thought if the first group (?:([A-Za-z]+):) is a non-capturing group then why it is returning http string in the output array.

我想如果第一个组(?:([a- za -z]+):)是一个非捕获组,那么它为什么在输出数组中返回http字符串。

So if you notice that there is a nested group ([A-Za-z]+) inside the non-capturing group. That nested group ([A-Za-z]+) is a capturing group (not having ?: at the beginning) in itself inside a non-capturing group (?:([A-Za-z]+):). That's why the text http still gets captured but the colon : character which is inside the non-capturing group but outside the capturing group doesn't get reported in the output array.

因此,如果您注意到在非捕获组中有一个嵌套组([a- za -z]+)。嵌套组([a- za -z]+)是一个捕获组(在开始时没有),在一个非捕获组中(?:([a- za -z]+):)。这就是为什么文本http仍然被捕获,但是冒号:在非捕获组内部的字符,但是在捕获组之外的字符在输出数组中没有被报告。

#11


1  

I think I would give you the answer, Don't use capture variables without checking that the match succeeded.

我想我会给你答案,不要在没有检查匹配成功的情况下使用捕捉变量。

The capture variables, $1, etc, are not valid unless the match succeeded, and they're not cleared, either.

捕获变量$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";
}

In the above example, To avoid capturing bronto in $1, (?:) is used. If the pattern is matched , then $1 is captured as next grouped pattern. So, the output will be as below:

在上面的例子中,为了避免捕获bronto $1,(?:)使用。如果模式匹配,则$1被捕获为下一个分组模式。因此,输出如下:

Fred wants a burger

It is Useful if you don't want the matches to be saved .

如果您不希望将匹配保存,那么它是有用的。

#12


1  

I cannot comment on the top answers to say this: I would like to add an explicit point which is only implied in the top answers:

我不能对上面的回答作出评论:我想要添加一个明确的点,这只是在上面的答案中所暗示的:

The non-capturing group (?...) does not remove any characters from the original full match, it only reorganises the regex visually to the programmer.

非捕获组(?…)没有从原始的完整匹配中移除任何字符,它只会将正则表达式重新组织到程序员。

To access a specific part of the regex without defined extraneous characters you would always need to use .group(<index>)

要访问regex的特定部分,而不需要定义额外的字符,您将总是需要使用.group( )

#1


1733  

Let me try to explain this with an example.

让我用一个例子来解释一下。

Consider the following text:

考虑以下文本:

https://*.com/
https://*.com/questions/tagged/regex

Now, if I apply the regex below over it...

现在,如果我把正则表达式应用到下面。

(https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

... I would get the following result:

…我将得到以下结果:

Match "https://*.com/"
     Group 1: "http"
     Group 2: "*.com"
     Group 3: "/"

Match "https://*.com/questions/tagged/regex"
     Group 1: "http"
     Group 2: "*.com"
     Group 3: "/questions/tagged/regex"

But I don't care about the protocol -- I just want the host and path of the URL. So, I change the regex to include the non-capturing group (?:).

但我不关心协议——我只想要URL的主机和路径。因此,我将regex更改为包含非捕获组(?:)。

(?:https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

Now, my result looks like this:

现在,我的结果是这样的:

Match "https://*.com/"
     Group 1: "*.com"
     Group 2: "/"

Match "https://*.com/questions/tagged/regex"
     Group 1: "*.com"
     Group 2: "/questions/tagged/regex"

See? The first group has not been captured. The parser uses it to match the text, but ignores it later, in the final result.

看到了吗?第一组没有被抓获。解析器使用它来匹配文本,但是在最后的结果中会忽略它。


EDIT:

As requested, let me try to explain groups too.

按照要求,让我试着解释一下小组。

Well, groups serve many purposes. They can help you to extract exact information from a bigger match (which can also be named), they let you rematch a previous matched group, and can be used for substitutions. Let's try some examples, shall we?

群体服务于许多目的。它们可以帮助您从更大的匹配(也可以命名)中提取准确的信息,它们让您重新匹配上一个匹配的组,并且可以用于替换。让我们来试几个例子,好吗?

Ok, imagine you have some kind of XML or HTML (be aware that regex may not be the best tool for the job, but it is nice as an example). You want to parse the tags, so you could do something like this (I have added spaces to make it easier to understand):

好的,假设您有某种XML或HTML(请注意,regex可能不是工作的最佳工具,但它是很好的示例)。您想要解析这些标记,所以您可以这样做(我添加了空格以使其更易于理解):

   \<(?<TAG>.+?)\> [^<]*? \</\k<TAG>\>
or
   \<(.+?)\> [^<]*? \</\1\>

The first regex has a named group (TAG), while the second one uses a common group. Both regexes do the same thing: they use the value from the first group (the name of the tag) to match the closing tag. The difference is that the first one uses the name to match the value, and the second one uses the group index (which starts at 1).

第一个regex有一个命名组(TAG),第二个regex使用一个公共组。两个regex都做同样的事情:它们使用第一个组(标记的名称)的值来匹配结束标记。不同之处在于,第一个使用名称来匹配值,第二个使用组索引(从1开始)。

Let's try some substitutions now. Consider the following text:

现在我们来做一些替换。考虑以下文本:

Lorem ipsum dolor sit amet consectetuer feugiat fames malesuada pretium egestas.

Now, let's use the this dumb regex over it:

现在,让我们用这个愚蠢的正则表达式:

\b(\S)(\S)(\S)(\S*)\b

This regex matches words with at least 3 characters, and uses groups to separate the first three letters. The result is this:

这个regex匹配至少3个字符的单词,并使用组分隔前三个字母。结果是这样的:

Match "Lorem"
     Group 1: "L"
     Group 2: "o"
     Group 3: "r"
     Group 4: "em"
Match "ipsum"
     Group 1: "i"
     Group 2: "p"
     Group 3: "s"
     Group 4: "um"
...

Match "consectetuer"
     Group 1: "c"
     Group 2: "o"
     Group 3: "n"
     Group 4: "sectetuer"
...

So, if we apply the substitution string...

如果我们应用替换字符串…

$1_$3$2_$4

... over it, we are trying to use the first group, add an underscore, use the third group, then the second group, add another underscore, and then the fourth group. The resulting string would be like the one below.

…在上面,我们尝试使用第一组,添加下划线,使用第三组,然后第二组,再加一个下划线,然后第四组。得到的字符串将与下面的字符串类似。

L_ro_em i_sp_um d_lo_or s_ti_ a_em_t c_no_sectetuer f_ue_giat f_ma_es m_la_esuada p_er_tium e_eg_stas.

You can use named groups for substitutions too, using ${name}.

您也可以使用命名组进行替换,使用${name}。

To play around with regexes, I recommend http://regex101.com/, which offers a good amount of details on how the regex works; it also offers a few regex engines to choose from.

为了与regex进行交互,我推荐http://regex101.com/,它提供了大量关于regex工作的详细信息;它还提供了一些regex引擎可供选择。

#2


128  

You can use capturing groups to organize and parse an expression. A non-capturing group has the first benefit, but doesn't have the overhead of the second. You can still say a non-capturing group is optional, for example.

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

Say you want to match numeric text, but some numbers could be written as 1st, 2nd, 3rd, 4th,... If you want to capture the numeric part, but not the (optional) suffix you can use a non-capturing group.

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

([0-9]+)(?:st|nd|rd|th)?

That will match numbers in the form 1, 2, 3... or in the form 1st, 2nd, 3rd,... but it will only capture the numeric part.

这将匹配表格1、2、3…或者在表格1,2,3,…但它只会捕获数值部分。

#3


83  

?: is used when you want to group an expression, but you do not want to save it as a matched/captured portion of the string.

?:当您想要对表达式进行分组时,但不希望将其保存为字符串的匹配/捕获部分。

An example would be something to match an IP address:

一个例子可以匹配一个IP地址:

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

Note that I don't care about saving the first 3 octets, but the (?:...) grouping allows me to shorten the regex without incurring the overhead of capturing and storing a match.

注意,我不关心保存前3个octets,但是(?:…)分组使我可以缩短regex,而不需要捕获和存储匹配的开销。

#4


25  

It makes the group non-capturing, which means that the substring matched by that group will not be included in the list of captures. An example in ruby to illustrate the difference:

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

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

#5


12  

Groups that capture you can use later on in the regex to match OR you can use them in the replacement part of the regex. Making a non-capturing group simply exempts that group from being used for either of these reasons.

捕获您的组可以在regex中稍后使用,或者您可以在regex的替换部分使用它们。使一个非捕获组简单地使该组免于被用于上述任何一个原因。

Non-capturing groups are great if you are trying to capture many different things and there are some groups you don't want to capture.

如果你试图捕捉许多不同的东西,并且有一些你不想捕捉的群体,那么非捕捉组是非常棒的。

Thats pretty much the reason they exist. While you are learning about groups, learn about Atomic Groups, they do a lot! There is also lookaround groups but they are a little more complex and not used so much.

这就是它们存在的原因。当你学习有关群体的知识时,学习原子组,他们做了很多!也有观察组,但他们比较复杂,不怎么使用。

Example of using later on in the regex (backreference):

稍后在regex中使用的示例(backreference):

<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1> [ Finds an xml tag (without ns support) ]

<([a - z][A-Z0-9]*)\[^ >]* b >。* ? [找到一个xml标签(没有ns支持)]

([A-Z][A-Z0-9]*) is a capturing group (in this case it is the tagname)

(a - z) [a - z0 -9]*)是一个捕获组(在本例中它是tagname)

Later on in the regex is \1 which means it will only match the same text that was in the first group (the ([A-Z][A-Z0-9]*) group) (in this case it is matching the end tag).

稍后在regex中是\1,这意味着它将只匹配第一个组中的相同文本(([A-Z][A-Z0-9]*)组)(在本例中它是匹配结束标记)。

#6


12  

HISTORICAL MOTIVATION: The existence of non-capturing groups can be explained with the use of parenthesis. Consider the expressions (a|b)c and a|bc, due to priority of concatenation over |, these expressions represent two different languages ({ac, bc} and {a, bc} respectively). However, the parenthesis are also used as a matching group (as explained by the other answers...).

历史动机:非捕获组的存在可以用括号来解释。考虑到表达式(|b)c和|bc,由于在|上的连接优先级,这些表达式分别表示两种不同的语言({ac, bc}和{a, bc})。然而,括号也用作匹配组(如其他答案所解释…)。

When you want to have parenthesis but not capture the subexpression you use NON-CAPTURING GROUPS. In the example, (?:a|b)c

当您想要有括号但不捕获子表达式时,您可以使用非捕获组。在这个例子中,(?:| b)c

#7


6  

Well I am a JavaScript developer and will try to explain its significance pertaining to JavaScript.

我是一个JavaScript开发人员,将尝试解释它与JavaScript相关的意义。

Consider a scenario where you want to match cat is animal when you would like match cat and animal and both should have a is in between them.

考虑这样一个场景:当你想要匹配猫和动物时,你想要匹配猫是动物,两者之间应该有一个。

 // this will ignore "is" as that's is what we want
"cat is animal".match(/(cat)(?: is )(animal)/) ;
result ["cat is animal", "cat", "animal"]

 // using lookahead pattern it will match only "cat" we can
 // use lookahead but the problem is we can not give anything
 // at the back of lookahead pattern
"cat is animal".match(/cat(?= is animal)/) ;
result ["cat"]

 //so I gave another grouping parenthesis for animal
 // in lookahead pattern to match animal as well
"cat is animal".match(/(cat)(?= is (animal))/) ;
result ["cat", "cat", "animal"]

 // we got extra cat in above example so removing another grouping
"cat is animal".match(/cat(?= is (animal))/) ;
result ["cat", "animal"]

#8


6  

Let me try this with an example :-

让我用一个例子来试试:-。

Regex Code :- (?:animal)(?:=)(\w+)(,)\1\2

正则表达式代码:-(?:动物)(:=)(\ w +)1(,)\ \ 2

Search String :-

搜索字符串:

Line 1 - animal=cat,dog,cat,tiger,dog

1号线-动物=猫、狗、猫、虎、狗

Line 2 - animal=cat,cat,dog,dog,tiger

行2 -动物=猫,猫,狗,狗,老虎

Line 3 - animal=dog,dog,cat,cat,tiger

3号线-动物=狗,狗,猫,猫,老虎

(?:animal) --> Non-Captured Group 1

(动物)->未捕获的第一组。

(?:=)--> Non-Captured Group 2

(? =)——>未捕获组2

(\w+)--> Captured Group 1

(\ w +)- - >组1

(,)--> Captured Group 2

(,)- - >组2捕获

\1 --> result of captured group 1 i.e In Line 1 is cat,In Line 2 is cat,In Line 3 is dog.

\1——捕获组1的>结果。e在第1行是cat,第2行是cat,第3行是dog。

\2 -->result of captured group 2 i.e comma(,)

\2——捕获组2的>结果。e逗号(,)

So in this code by giving \1 and \2 we recall or repeat the result of captured group 1 and 2 respectively later in the code.

因此,在这段代码中,我们回忆或重复了在代码中稍后捕获的第1组和第2组的结果。

As per the order of code (?:animal) should be group 1 and (?:=) should be group 2 and continues..

按照代码的顺序(?:动物)应该是第1组,并且(? =)应该是第2组,并且继续。

but by giving the ?: we make the match-group non captured(which do not count off in matched group, so the grouping number starts from the first captured group and not the non captured), so that the repetition of the result of match-group (?:animal) can't be called later in code.

但是通过给予?:我们使match-group不被捕获(在匹配的组中没有计数,所以分组编号从第一个被捕获的组开始,而不是未捕获的),这样就不能在代码中调用match-group (?:animal)的结果。

Hope this explains the use of non capturing group.

希望这可以解释为什么使用非捕获组。

enter image description here

在这里输入图像描述

#9


5  

In complex regular expressions you may have the situation arise where you wish to use a large number of groups some of which are there for repetition matching and some of which are there to provide back references. By default the text matching each group is loaded into the backreference array. Where we have lots of groups and only need to be able to reference some of them from the backreference array we can override this default behaviour to tell the regular expression that certain groups are there only for repetition handling and do not need to be captured and stored in the backreference array.

在复杂的正则表达式中,您可能会出现这样的情况:您希望使用大量的组,其中一些组用于重复匹配,其中一些用于提供反向引用。默认情况下,将每个组匹配的文本加载到backreference数组中。我们有很多团体,只需要能够从backreference数组引用其中一些我们能够覆盖这个默认的行为告诉某些群体的正则表达式重复处理,不需要捕获并存储在backreference数组。

#10


2  

One interesting thing that I came across is the fact that you can have a capturing group inside a non-capturing group. Have a look at below regex for matching web urls:

我遇到的一个有趣的事情是,你可以在一个非捕获组中拥有一个捕获组。在regex下面查看匹配的web url:

var parse_url_regex = /^(?:([A-Za-z]+):)(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

Input url string:

输入url字符串:

var url = "http://www.ora.com:80/goodparts?q#fragment";

The first group in my regex (?:([A-Za-z]+):) is a non-capturing group which matches the protocol scheme and colon : character i.e. http: but when I was running below code, I was seeing the 1st index of the returned array was containing the string http when I was thinking that http and colon : both will not get reported as they are inside a non-capturing group.

第一组在我的正则表达式(?:([A-Za-z]+):)是一群无匹配的协议方案和结肠癌:性格即http:但我运行下面的代码的时候,我看到第一索引返回的数组是包含字符串http认为http和结肠的时候:不会得到报告,因为他们都是在一个无组。

console.debug(parse_url_regex.exec(url));

什么是非捕获组?(?)做什么?

I thought if the first group (?:([A-Za-z]+):) is a non-capturing group then why it is returning http string in the output array.

我想如果第一个组(?:([a- za -z]+):)是一个非捕获组,那么它为什么在输出数组中返回http字符串。

So if you notice that there is a nested group ([A-Za-z]+) inside the non-capturing group. That nested group ([A-Za-z]+) is a capturing group (not having ?: at the beginning) in itself inside a non-capturing group (?:([A-Za-z]+):). That's why the text http still gets captured but the colon : character which is inside the non-capturing group but outside the capturing group doesn't get reported in the output array.

因此,如果您注意到在非捕获组中有一个嵌套组([a- za -z]+)。嵌套组([a- za -z]+)是一个捕获组(在开始时没有),在一个非捕获组中(?:([a- za -z]+):)。这就是为什么文本http仍然被捕获,但是冒号:在非捕获组内部的字符,但是在捕获组之外的字符在输出数组中没有被报告。

#11


1  

I think I would give you the answer, Don't use capture variables without checking that the match succeeded.

我想我会给你答案,不要在没有检查匹配成功的情况下使用捕捉变量。

The capture variables, $1, etc, are not valid unless the match succeeded, and they're not cleared, either.

捕获变量$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";
}

In the above example, To avoid capturing bronto in $1, (?:) is used. If the pattern is matched , then $1 is captured as next grouped pattern. So, the output will be as below:

在上面的例子中,为了避免捕获bronto $1,(?:)使用。如果模式匹配,则$1被捕获为下一个分组模式。因此,输出如下:

Fred wants a burger

It is Useful if you don't want the matches to be saved .

如果您不希望将匹配保存,那么它是有用的。

#12


1  

I cannot comment on the top answers to say this: I would like to add an explicit point which is only implied in the top answers:

我不能对上面的回答作出评论:我想要添加一个明确的点,这只是在上面的答案中所暗示的:

The non-capturing group (?...) does not remove any characters from the original full match, it only reorganises the regex visually to the programmer.

非捕获组(?…)没有从原始的完整匹配中移除任何字符,它只会将正则表达式重新组织到程序员。

To access a specific part of the regex without defined extraneous characters you would always need to use .group(<index>)

要访问regex的特定部分,而不需要定义额外的字符,您将总是需要使用.group( )