字符串的重新组成部分:(?:...)神秘

时间:2017-01-19 15:59:13

标签: python regex string

我有一个字符串:

temp = '4424396.6\t1\tk__Bacteria\tp__Firmicutes\tc__Erysipelotrichi\to__Erysipelotrichales'

我只需要在分类术语之间摆脱制表。

我试过

re.sub(r'(?:\D{1})\t', ',', temp)

它非常接近,但也替换了标签前的字母:

'4424396.6\t1\tk__Bacteri,p__Firmicute,c__Erysipelotrich,o__Erysipelotrichales'

我感到困惑,因为(?:...)的重新文档是:

  

...之后无法检索该组匹配的子字符串   执行匹配或稍后在模式中引用。

最后一个字母在括号内,所以怎么能被替换?

PS

我使用re.sub(r'(?<=\D{1})(\t)', ',', temp)并且它工作得非常好,但我无法理解第一个正则表达式的错误

2 个答案:

答案 0 :(得分:2)

(?:...)匹配的文字不会形成捕获组(...)也是如此,因此以后不能使用{{1}等反向引用来引用它}。但是,它仍然是整体匹配的一部分,并且是\1将替换的文本的一部分。

非捕获组的重点在于它们的效率稍高,并且在re.sub()等用途中可能需要使用捕获组的存在会影响输出。

答案 1 :(得分:1)

根据the documentation(?:...)指定非捕获组。它解释说:

  

有时您会想要使用组来收集正则表达式的一部分,但是对检索组的内容不感兴趣。

这意味着与...表达式(在您的情况下,前面的字母)匹配的任何内容都不会被捕获为组,但仍将是匹配的一部分。唯一特别之处在于,您将无法使用match.group访问该组捕获的输入部分:

  

除了无法检索组匹配内容的事实外,非捕获组的行为与捕获组完全相同

相比之下,(?<=...)是一个正向后视断言;正则表达式将检查以确保任何匹配前面都有匹配...的文本,但不会捕获该部分。