在嘈杂的文本中查找标点符号

时间:2015-11-04 10:04:36

标签: python regex string

我的句子使用了标点符号,例如:

Some people do it right; some forget a whitespace;some add a wrong one ; pretty annoying! ;)

我需要知道每个“真实”标点符号的位置,这些标记特别排除了它们在文本表情符号中的使用。如果我使用:

>>> print re.findall(r'\w+\s*(;)\s*\w+', s)
[';', ';', ';']

所以我正确匹配分号,但我没有在字符串中的位置。但是,当我使用finditer

>>> p = re.compile(r'\w+\s*(;)\s*\w+')
>>> for m in p.finditer(s):
...    print m.group(), m.span()
right; some (18, 29)
whitespace;some (39, 54)
one ; pretty (67, 79)

我正确地得到了整个匹配组。当我使用天真的方法时

>>> p = re.compile(r';')
>>> for m in p.finditer(s):
...     print m.group(), m.span()
; (23, 24)
; (49, 50)
; (71, 72)
; (90, 91)

我获得所有“真实”标点符号的位置,但也是;)表情符号的一部分。

该示例仅使用;,但它可以是各种标点符号:.,;:?!。另外,我不必担心十进制数字。

当然,我可以将\w+更改为[a-zA-Z]+,但这会干扰以数字结尾的句子,例如The answer is 42.

我想我可以在个别群体中应用天真的方法,但也许有一种更简单的方法来做到这一点。

1 个答案:

答案 0 :(得分:0)

当不带参数调用时,match.group返回整个匹配。在您的正则表达式模式中,包含;的组可以称为1.

使用组名作为参数调用匹配对象的start方法:

for m in p.finditer(s):
    print(m.start(1), s[m.start(1)])

输出

23 ;
49 ;
71 ;

考虑指定一个符号组名称,您可以使用它来代替1,例如

p = re.compile(r'\w+\s*(?P<semicolon>;)\s*\w+')
for m in p.finditer(s):
    print(m.start('semicolon'), s[m.start('semicolon')])

输出相同。