用例?:在tcl regexp中

时间:2016-07-18 14:07:25

标签: regex tcl

我在tcl regexp中阅读了?:的文档。这表示它与表达式匹配而没有捕获它。

我试过,它工作正常。 我的查询是,这个选项的正确用例是什么,因为我们不想使用捕获序列,我们不会在那里放括号。

这只是一种替代方式,还是有一些特殊情况,我们应该使用它?请澄清。

3 个答案:

答案 0 :(得分:3)

简单:您需要在正则表达式中对多个元素进行分组,但您不需要将它们作为捕获组进行参考。

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

我需要大括号进行分组。但如果我像这样运行引擎将捕获所有这些匹配。这可能需要大量内存并且需要大量性能。如果我以后不需要捕获组作为参考,我可以使用?:进行分组而不会影响性能:

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

答案 1 :(得分:2)

首先,看看Tcl正则表达式引用:

  

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

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

考虑到这一点,使用非捕获组可以大大简化Tcl正则表达式的使用,以防您拥有包含多个捕获组的模式,并且您希望通过在现有的中间添加另一个组来修改它组即可。

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

regexp {(\w+)\s+(\d+)\s+\(([^()]+)\)} $a - body num comment

但是,系统还要求您在wordspace之间匹配任意数量的digits + 1234 + comment字符串。如果你写

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将保留您不希望的值。

将其转换为 - 捕获组可解决此问题。

请参阅IDEONE demo

对于非捕获组的其他常见用途,请参阅Are optional non-capturing groups redundant帖子。

答案 2 :(得分:1)

在匹配多个单词选项时,您可以在正则表达式中使用()个括号,然后您不想捕获它们。

(?:one|two|three)