3

我想在像a.b.c.d(becomes abcd) 这样的词中省略点,但在某些情况下:

  • 单词中至少应该有 2 个点,例如,a.b仍然是a.b,但是a.b.c是匹配的。
  • 这应该只匹配 1 或 2 个字母。例如,a.bb.c是匹配项(因为a,bbc分别是 1 或 2 个字母),但aaa.b.cc不是匹配项(因为aaa由 3 个字母组成)

这是我迄今为止尝试过的:

import re
texts = [
    'a.b.c', # Should be: 'abc'
    'ab.c.dd.ee', # Should be: 'abcddee'
    'a.b' # Should remain: 'a.b'
]
for text in texts:
    text = re.sub(r'((\.)(?P<word>[a-zA-Z]{1,2})){2,}', r'\g<word>', text)
    print(text)

这将选择“任何点后跟 1 或 2 个字母”,重复 2 次或更多次。选择工作正常,但用组替换,只导致最后一场比赛,重复被忽略。

所以,它打印:

ac
abee
a.b

这不是我想要的。我会很感激任何帮助,谢谢。

4

2 回答 2

2

用点开始比赛并.不能确保在它之前有一个 char a-zA-Z。

如果您word在替换中使用命名组,它将包含最后一次迭代的值,因为它本身在重复组中。


您可以将 2 个或多个点与 char a-zA-Z 的 1 次或 2 次匹配,并在匹配时用空字符串替换这些点。

为防止aaa.b.cc匹配,您可以使用单词边界\b

\b[a-zA-Z]{1,2}(?:\.[a-zA-Z]{1,2}){2,}\b

模式匹配:

  • \b防止单词成为更大单词的一部分的单词边界
  • [a-zA-Z]{1,2}匹配 1 或 2 次 char a-zA-Z
  • (?:非捕获组
    • \.[a-zA-Z]{1,2}匹配一个点和一个字符 a-zA-Z 的 1 或 2 次
  • ){2,}关闭非捕获组并重复 2 次或更多次以匹配至少 2 个点
  • \b一个词的边界

正则表达式演示| Python 演示

import re

pattern = r"\b[a-zA-Z]{1,2}(?:\.[a-zA-Z]{1,2}){2,}\b"
texts = [
    'a.b.c',
    'ab.c.dd.ee',
    'a.b',
    'aaa.b.cc'
]

for s in texts:
    print(re.sub(pattern, lambda x: x.group().replace(".", ""), s))

输出

abc
abcddee
a.b
aaa.b.cc
于 2021-04-07T08:57:22.583 回答
2
^(?=(?:.*?\.){2,}.*$)[a-z]{1,2}(?:\.[a-z]{1,2})+$

您可以使用它来匹配字符串。如果匹配,您可以.使用任何简单的方法删除。

见演示。

https://regex101.com/r/BrNBtk/1

于 2021-04-07T09:04:33.843 回答