正则表达式中的 (?: 是什么意思?

38

我遇到了一个正则表达式,但是我并不完全理解它 - 有人可以帮我解密一下吗:

^home(?:\/|\/index\.asp)?(?:\?.+)?$

它用于URL匹配,上面的例子匹配以下URL:

home
home/
home/?a
home/?a=1
home/index.asp
home/index.asp?a
home/index.asp?a=1

我认为括号中的问号标记 (?: 并没有什么作用。有人能给我解释一下吗?

使用的正则表达式版本是Classic ASP提供的,并在服务器上运行,如果这有助于解释。


6
正则表达式圣经网站是regular-expressions.info。它包含有关正则表达式的所有知识和清晰易懂的解释。 - Bohemian
@Bohemian 非捕获组 (?:regex) 在页面 https://www.regular-expressions.info/refcapture.html 中列出。 - NZD
4个回答

48

(?:) 创建一个非捕获组。它将内容组合在一起,但不会创建回溯引用。

回溯引用是表达式中可以引用或替换的部分(通过使用 \1$1 等 - 取决于具体情况)。在使用编程语言中的正则表达式时,您还可以从匹配中提取它们。使用(?:) 的主要原因是避免创建新的回溯引用,这样可以避免增加组号,特别是当您重复一个组并且不希望出现不可预测的组号时,也可以节省(通常为微不足道的)内存。


这意味着它允许分组(在您的示例中,这对于使用 | 选择替代方案非常有用),同时不创建捕获组(您可以在其他地方引用或从成功匹配中提取的内容)。 - ebottard
某些正则表达式函数可以让你从正则表达式中获取特定的组,例如第一个括号分组、第二个等等。如果你使用非捕获分组,它不会添加到编号中,也不能作为单独的组获取。(这可能会更快一些。) - Brett Zamir
有时候避免捕获括号组是至关重要的。分组匹配可以被重复利用(例如使用 +* 在括号外部),创建了一个未知数量的捕获组。这时,要在输入中反向引用后续的匹配就变得棘手了,因为在编写正则表达式时它们的编号是不确定的。使用非捕获组来重复避免了这个问题。 - Bob Sammers

15

这是一个非捕获组,本质上与使用(...)相同,但内容不会被保留(无法通过反向引用获取)。

如果您正在执行以下操作:(abc)(?:123)(def),则$1中将得到abc$2中将得到def,但只能匹配123


2

来自文档:

(?:...)
A non-capturing version of regular parentheses. Matches whatever regular expression is inside the parentheses, but the substring matched by the group cannot be retrieved after performing a match or referenced later in the pattern.

1

这很简单。每个括号都会在内存中创建一个变量,因此您可以在之后使用括号的值,因此,为了不将其保存在内存中,请在括号中放置:?,像这样(?:),然后按照需要填写剩余部分即可。就是这样,没有其他。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接