?的用例:在tcl regexp中

?的用例:在tcl regexp中,regex,tcl,Regex,Tcl,我阅读了tcl regexp中的?:文档。也就是说它匹配一个表达式而不捕获它 我试过了,效果很好。 我的问题是,这个选项的合适用例是什么,因为我们不想使用捕获序列,所以我们不会把括号放在那里 这只是一种替代方法,还是有一些特殊条件,我们应该在哪里使用它?请澄清。在匹配多个不想捕获的单词选项时,您可以在正则表达式中使用括号 (?:one|two|three) 简单:您需要在正则表达式中对几个元素进行分组,但不需要将它们作为引用的捕获组 a+ (b+|c+) OR (a+ b+)|c+ 我需要大

我阅读了tcl regexp中的
?:
文档。也就是说它匹配一个表达式而不捕获它

我试过了,效果很好。 我的问题是,这个选项的合适用例是什么,因为我们不想使用捕获序列,所以我们不会把括号放在那里

这只是一种替代方法,还是有一些特殊条件,我们应该在哪里使用它?请澄清。

在匹配多个不想捕获的单词选项时,您可以在正则表达式中使用括号

(?:one|two|three)

简单:您需要在正则表达式中对几个元素进行分组,但不需要将它们作为引用的捕获组

a+ (b+|c+) OR (a+ b+)|c+
我需要大括号来分组。但如果我这样运行,引擎将捕获所有匹配项。这可能需要大量内存,并会降低性能。如果我以后不需要捕获组作为参考,我可以使用?:在不影响性能的情况下获取分组:

a+ (?:b+|c+) OR (?:a+ b+)|c+

首先,看看Tcl正则表达式参考:

(表达式)

表达式周围的括号指定嵌套表达式。子字符串匹配表达式被捕获,可以通过反向引用机制进行引用,也可以捕获到指定为命令参数的任何相应匹配变量中。
(?:表达式)

匹配表达式而不捕获它

虽然第一部分描述了捕获组捕获要使用反向引用引用的子文本的能力是通用的,但第二部分描述了基于捕获组初始化变量的能力是特定于Tcl的

记住这一点,如果您有一个包含多个捕获组的模式,并且希望通过在现有组之间添加另一个组来修改它,那么使用非捕获组可以大大简化Tcl正则表达式的使用

比方说,您希望匹配像abc 1234(comment)这样的字符串,并使用
{(\w+)\s+(\d+)\s+\([^()]+\)}

但是,还要求您将字符串与
1234
注释之间的任意数量的
word
+
空格
+
数字
进行匹配。如果你写信

set a1 "abc 1234 more 5678 text 890 here 678 (comment)"
regexp {(\w+)\s+(\d+)(\s+\w+\s+\d+)*\s+\(([^()]+)\)} $a - body1 num1 comment1
                     ^^^^^^^^^^^^^^^
$comment
将包含一个您不期望的值

将其转换为非捕获组可以解决此问题


对于非捕获组的其他常见用途,请参阅POST。< /P>见这里,我不认为它是对该答案的一种欺骗,因为TCL有它自己的正则表达式,它使用了大量的内存,并且花费了大量的性能。这实际上并不是一个消耗资源的操作。关键是,没有创建和填充组的堆栈,但并不总是要求进行操作。主要的一点是,非捕获组仅用于分组,而不用于其他目的,因此,不会破坏模式中已定义的捕获组的现有顺序,我在其他问题中运行了一些基准测试,其中单个组的运行时间减少了30%,我认为可以构建更多的示例,但在重复问题的伟大答案中讨论了其中许多要点,我认为这一点很快就会接近我不会关闭这一点,然而,我希望得到一个更为详细的答案,这是为Tcl量身定做的。非捕获组非常有用。@Mariano为下一个程序员编写明确的代码有什么意义?我试着把我的正则表达式写得尽可能清晰易读。你还需要进一步澄清吗?如果你这样做了,请不要犹豫发表评论。

set a1 "abc 1234 more 5678 text 890 here 678 (comment)"
regexp {(\w+)\s+(\d+)(\s+\w+\s+\d+)*\s+\(([^()]+)\)} $a - body1 num1 comment1
                     ^^^^^^^^^^^^^^^