我有一个字符串:
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)
并且它工作得非常好,但我无法理解第一个正则表达式的错误
答案 0 :(得分:2)
与(?:...)
匹配的文字不会形成捕获组,(...)
也是如此,因此以后不能使用{{1}等反向引用来引用它}。但是,它仍然是整体匹配的一部分,并且是\1
将替换的文本的一部分。
非捕获组的重点在于它们的效率稍高,并且在re.sub()
等用途中可能需要使用捕获组的存在会影响输出。
答案 1 :(得分:1)
根据the documentation,(?:...)
指定非捕获组。它解释说:
有时您会想要使用组来收集正则表达式的一部分,但是对检索组的内容不感兴趣。
这意味着与...
表达式(在您的情况下,前面的字母)匹配的任何内容都不会被捕获为组,但仍将是匹配的一部分。唯一特别之处在于,您将无法使用match.group
访问该组捕获的输入部分:
除了无法检索组匹配内容的事实外,非捕获组的行为与捕获组完全相同
相比之下,(?<=...)
是一个正向后视断言;正则表达式将检查以确保任何匹配前面都有匹配...
的文本,但不会捕获该部分。