我想用re.finditer获取一个字符串中的单词的起始和终止索引号,大部分情况下我的模式都能正常工作,但是对于一个带有特殊字符的单词,我的regex给了我一个错误信息
问题:
我试过了
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)]
对于大多数情况下,我的模式工作正常,但是对于带有特殊字符的单词,我遇到了问题。
编码:
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('c++, c##')
第二个问题是,字的边界,对于特殊字符,它们不会像对于字母数字字符那样表现出相同的方式,例如 \bfoo\b
引用python文档中的话
\b 字界
匹配空字符串,但只在一个词的开头或结尾处。 一个词被定义为一个字母数字或下划线字符的序列,所以一个词的结尾由空格或一个非字母数字、非下划线字符表示。请注意,从形式上讲,/b被定义为一个/w和一个/W字符之间的边界(反之亦然),或者是/w和字符串开头的边界,所以被认为是字母数字的字符集取决于UNICODE和LOCALE标志的值。例如,r'\bfoo/b'可以匹配'foo'、'foo.'、'(foo)'、'bar foo baz',但不能匹配'foobar'或'foo3'。
为了使这一问题得到解决,你可以使用正向的lookahead断言。
r'\b{}(?=\s|$)'
它在寻找一个空白的地方 (\s)
字 ($)
在你的模式之后