Python 后视正则表达式 "fixed-width pattern" 查找连续重复的词时出错

Python look-behind regex "fixed-width pattern" error while looking for consecutive repeated words

我有一个文本,其中的单词由 . 分隔,其中有 2 个和 3 个连续重复的单词:

My.name.name.is.Inigo.Montoya.You.killed.my.father.father.father.Prepare.to.die-

我需要用正则表达式独立匹配它们,排除一式三份中的重复项。

因为最多。 3个连续重复的单词,this

r'\b(\w+)\.+\.+\b'

成功捕获

father.father.father

但是,为了捕捉 2 个连续的重复词,我需要确保下一个词和上一个词不相同。我可以做一个负向预测

r'\b(\w+)\.+(?!\.+)\b'

但我在负面回顾

中的尝试

r'(?<!(\w)\.)\b\.+\b(?!\.)'

return 固定宽度问题(当我保留 + 时)或其他问题。

我应该如何纠正负面回顾

我认为可能有一种更简单的方法来捕捉您想要的内容,而无需消极的回顾:

r = re.compile(r'\b((\w+)\.+\.+?)\b')
r.findall(t)

> [('name.name.', 'name'), ('father.father.father', 'father')]

只是将第三次重复设为可选。


一个版本可以捕获任意数量的同一个词的重复,看起来像这样:

r = re.compile(r'\b((\w+)(\.+)*)\b')
r.findall(t)
> [('name.name', 'name', '.name'), ('father.father.father', 'father', '.father')]

也许根本不需要正则表达式。

使用 itertools.groupby 就可以了。 设计 将连续项目的相等出现分组。

  • 按词分组(按点拆分后)
  • 转换为列表并发出一个tuple值,仅当长度> 1时才计数

像这样:

import itertools

s = "My.name.name.is.Inigo.Montoya.You.killed.my.father.father.father.Prepare.to.die"

matches = [(l[0],len(l)) for l in (list(v) for k,v in itertools.groupby(s.split("."))) if len(l)>1]

结果:

[('name', 2), ('father', 3)]

所以基本上我们可以用这个元组列表做任何我们想做的事情(例如根据出现次数过滤它)

奖金(因为我一开始误读了这个问题,所以我把它留在了):从句子中删除重复项 - 像上面那样按单词分组(按点拆分后) - 仅获取列表 comp 中返回值的键(值)(我们不需要这些值,因为我们不计算) - 加入点

在一行中(仍然使用itertools):

new_s = ".".join([k for k,_ in itertools.groupby(s.split("."))])

结果:

My.name.is.Inigo.Montoya.You.killed.my.father.Prepare.to.die