如何编写一个表达式来精确匹配同一字符(或者,理想情况下,同一组)的 N 次重复?基本上,(.)\1{N-1}
做了什么,但有一个重要的限制:如果主题重复更多 次,则表达式应该失败。例如,给定 N=4
和字符串 xxaaaayyybbbbbzzccccxx
,表达式应该匹配 aaaa
和 cccc
而不是 bbbb
。
我不专注于任何特定的方言,请随意使用任何语言。请不要发布仅适用于此特定示例的代码,我正在寻找通用解决方案。
最佳答案
使用否定前瞻和否定回顾。
这将是正则表达式:(.)(?<!\1.)\1{N-1}(?!\1)
除了 Python 的 re 模块坏了(见 this link )。
英文翻译:“匹配任何字符。确保在匹配该字符之后,它之前的字符也不是该字符。匹配该字符的 N-1 次重复。确保这些重复之后的字符是也不是那个角色。”
不幸的是,re 模块(和大多数正则表达式引擎)被破坏了,因为您不能在后向断言中使用反向引用。 Lookbehind assertions 必须是恒定长度,并且编译器不够聪明,无法推断它是在使用反向引用时(即使在这种情况下,backref 是恒定长度)。我们必须通过这个来控制正则表达式编译器,如下所示:
实际答案 必须更加困惑:r"(.)(?<!(?=\1)..)\1{N-1}(?!\1)"
这通过使用 (?=\1)..
解决了 re 模块中的错误。而不是 \1.
(这些在大多数情况下是等价的。)这让正则表达式引擎准确地知道 lookbehind 断言的宽度,因此它可以在 PCRE 和 re 等中工作。
当然,现实世界的解决方案类似于 [x.group() for x in re.finditer(r"(.)\1*", "xxaaaayyybbbbbzzccccxx") if len(x.group()) == 4]
关于java - 精确匹配同一字符的 N 次重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10319696/