正则表达式在re.finditer中如何包含特殊字符的模式

3

我试图使用re.finditer获取字符串中单词的起始和结束索引号。

对于大多数情况,我的模式工作正常,但是对于具有特殊字符的单词,我的正则表达式会导致错误。

问题:

我尝试了:

a = " we have c++ and c#"
pattern = ['c#','c++']
regex = re.compile(r'\b(' + '|'.join(pattern) + r')\b')
out = [ (m.start(0), m.end(0)) for m in regex.finditer(a)]

当前输出:

error: multiple repeat at position x

期望输出:

[(9,12),(17,19)]

大多数情况下,我的模式都能正常工作, 但是涉及到特殊字符的单词时,我遇到了问题。 我对正则表达式不太熟悉,请有经验的人帮忙解决一下,谢谢!

1个回答

3

代码:

a = " we have c++ and c#"
pattern = [ r'\b{}(?=\s|$)'.format(re.escape(s)) for s in ['c#','c++']]
regex = re.compile('|'.join(pattern))
[ (m.start(0), m.end(0)) for m in regex.finditer(a)]

细节:

第一个问题是特殊字符;您可以手动转义特殊字符。

'c\\+\\+', 'c\\#\\#']

或者,您可以使用re.escape来简化操作,它将为您完成此工作。
re.escape('c++, c##')

第二个问题是单词边界,特殊字符与字母数字字符的行为不同,例如\bfoo\b 引用自Python文档: word boundary 匹配空字符串,但仅在单词的开头或结尾。单词被定义为字母数字或下划线字符的序列,因此单词的结尾由空格或非字母数字、非下划线字符表示。请注意,正式地说,\b被定义为\w和\W字符(或反之亦然)之间的边界,或者在字符串的开头/结尾和\w之间的边界,因此被视为字母数字字符的确切字符集取决于UNICODE和LOCALE标志的值。例如,r'\bfoo\b'匹配'foo'、'foo.'、'(foo)'、'bar foo baz',但不匹配'foobar'或'foo3'。
要使其工作,您可以使用正向先行断言。 r'\b{}(?=\s|$)' 它在您的模式后寻找空格字符 (\s) 或句子结尾 ($)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接