正则表达式在字符串中匹配单词两次
我想找到一种方法,能够检测到字符串中任何全大写单词(或者它的部分)出现两次的位置。以下是一些例子——我想检测到的部分用粗体标出:
- 00004 ADC SOME RANDOM WORDS ADC 其他无关字符
- 02 SOME CANIT CAN 其他无关的200
- 399 ADC0 FLAG ADC0 更多单词 adc
我现在有的(在网上的正则表达式解析器上看起来有效)是这个:
p = re.compile('( [A-Z]{2,}[A-Z0-9]*).*(\1)')
match = p.search('0x0000 ADC asdf ADC')
print(match)
我尝试了不同的空格变体等等,但这导致匹配结果为None。有没有什么提示可以告诉我这个正则表达式哪里出错了?
2 个回答
1
这里说的是用法,应该是\\1
而不是\1
。
p = re.compile('( [A-Z]{2,}[A-Z0-9]*).*(\\1)')
2
在定义正则表达式模式时,建议使用原始字符串。具体可以参考这个讨论的第二和第三段,以及原始字符串表示法的解释。在你的例子中,'\1'
被解释成了单个字符chr(1)
:
In [173]: '\1'
Out[173]: '\x01'
In [181]: list('\1')
Out[181]: ['\x01']
而你其实想要的是两个字符,一个反斜杠和一个数字1:
In [180]: list(r'\1')
Out[180]: ['\\', '1']
In [176]: p = re.compile(r'( [A-Z]{2,}[A-Z0-9]*).*(\1)')
In [177]: p.search('0x0000 ADC asdf ADC')
Out[177]: <_sre.SRE_Match at 0xb439770>
另外,如果你想找到尽可能多的这种模式,建议使用非贪婪模式.*?
,而不是.*
:
In [195]: [(match.start(), match.end()) for match in re.finditer(r'\b([A-Z]{2,}[A-Z0-9]*).*?(\1)', '0x0000 ADC asdf ADC0 ADC ADC0')]
Out[195]: [(7, 19), (21, 28)]