2

我是正则表达式的新手。我有一个正则表达式,它从字符串中删除重复字符。

>>> self.repeat_regexp = re.compile(r'(\w*)(\w)\2(\w*)')
>>> self.repl = r'\1\2\3'

上面两行代码去掉了重复的字符。例如,loooooooove转到love

但我想更改正则表达式模式,以便仅在重复字符重复超过 3 次时才替换。预期输出:

cannot  ---> cannot
loooooooove ----> love

我不理解正则表达式r'(\w*)(\w)\2(\w*)'r'\1\2\3' 如果以可理解的方式解释上述正则表达式会很有帮助。

4

1 回答 1

7

我不理解正则表达式 --> r'(\w*)(\w)\2(\w*)' 和 r'\1\2\3' 如果将上述正则表达式解释为可以理解的方式。

好的,我们走吧:

(\w*)是任何类型的单词字符(字母、数字、下划线 - 因语言环境设置而异,可以包括带重音的法语字母),零次或多次(通过使用量词 *)。

接下来它尝试只匹配一个单词字符(\w)——然后再次使用相同的字符\2,这是对表达式中第二个匹配项的反向引用\w,它是之前匹配的字符。

之后,又是零个或多个单词字符,与开头相同。

如果该表达式匹配,则将其self.repl = r'\1\2\3'替换——再次使用反向引用——使用搜索模式中的括号捕获子模式的匹配项。

所以每个匹配的部分都会被自己替换——除了重复的字符 match \2,它没有分组括号。

因此,如果您想让重复的字符至少出现 3 次,则将表达式的那部分修改为(\w)(\2{2,})'{2,}是另一个量词,表示“仅当前面的模式至少出现两次时才匹配”。(至少两次,因为第一个字符已经与前面的字符匹配(\w)。)

虽然我没有让它使用前导和尾随工作(\w*)- 但由于这些也匹配零字字符,我认为它们可以完全抛弃。

所以这应该做你想要实现的目标:

self.repeat_regexp = re.compile(r'(\w)(\1{2,})')
self.repl = r'\1'

(由于我在这里删除了主要的捕获子模式,\2因此被替换为\1,引用了现在的第一个捕获子模式。)

于 2013-03-21T10:34:47.310 回答