有人能解释一下吗?:在正则表达式中

9

TCL: 有人能解释一下 ?: 在正则表达式中的含义吗?

我对 ? 和 ?: 之间的区别感到困惑。

? 表示前面的字符可能存在,也可能不存在。

那么我不理解 (?:) 的含义是什么。

有人可以解释一下吗?

([0-9]+(?:\.[0-9]*)?)

1
“?”在正则表达式中有很多特殊用途,其含义取决于其左侧的内容。这些含义通常彼此无关。 - Barmar
2
嗯,(? 的意思取决于接下来的1-2个字符。 - chx
@chx:除了在(?:)中使用的冒号,还有哪些可能改变含义的字符? - user2742564
2
我觉得我不可能列出所有的内容,可以查看http://www.regular-expressions.info/refadv.html获取大量的可能性:子表达式的修饰符、前瞻、条件语句,然后是像https://dev59.com/bVTTa4cB1Zd3GeqPpyc4这里描述的命名模式子程序。 - chx
3个回答

27

假设你正在尝试在输入字符串中查找类似于ABC123ABC123.45的内容,并且希望分别捕获字母和数字。您可以使用一个正则表达式(与您的正则表达式有点相似),例如:

([A-Z]+)([0-9]+(\.[0-9]+)?)
上面的正则表达式将匹配ABC123.45,并且提供三个代表整个匹配子部分的组,这些组是通过在哪里放置括号()来决定的。因此,给定我们的正则表达式(不使用?:),我们得到了:
Group 1 = ABC
Group 2 = 123.45
Group 3 = .45

现在,总是获取小数部分可能没有什么意义,并且它实际上已经在我们的第二组中捕获了。那么,你如何使这个组 () 不进行捕获呢?使用 ?: 在开头即可。

([A-Z]+)([0-9]+(?:\.[0-9]+)?)

现在,您只会得到两个所需的组

Group 1 = ABC
Group 2 = 123.45

注意,我还将正则表达式的最后一部分从\.[0-9]*更改为\.[0-9]+。这可以防止匹配123.,即没有小数部分但仍然带有点号的数字。


3

?: 不会创建捕获组。例如,a(?:b) 将匹配 "abc" 中的 "ab"。


2

如 Tcl 文档中的 re_syntax 手册所述,括号组内的 ?: 关闭该组的捕获。换句话说,表达式 (\d)(\d) 匹配 2 个数字并将每个数字分别放在不同的匹配组中。表达式 (\d)(?:\d) 类似,但不会在单独的匹配组中提供匹配项。对于 Tcl 特别适用:

regexp {(\d)(\d)} $data -> first second

将使第一个数字和第二个数字在命名变量中可用。相应的非收集正则表达式不会提供3个结果,而只提供目标中单个匹配的1个结果。因此,您的表达式具有两个输出,一个用于匹配的所有内容,另一个用于最外层括号。内部括号组成一个正则表达式组,但避免产生另一个匹配输出。因此,您拥有匹配十进制数(3.1415、0.、10)的内容。


这个 (?:) 语法只适用于TCL,还是任何使用正则表达式的语言都可以使用? - user2742564
它可以在其他语言中使用。 - Rahul Tripathi
@user2742564 这不是普遍存在的,但在高级 RE 引擎中非常常见。 - Donal Fellows

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