regex在re.finditer的模式中包含特殊字符。

问题描述 投票:0回答:1

我想用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)]

对于大多数情况下,我的模式工作正常,但是对于带有特殊字符的单词,我遇到了问题。

python-3.x regex
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('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)($) 在你的模式之后

© www.soinside.com 2019 - 2024. All rights reserved.