【问题标题】:Python regex remove dots from dot separated lettersPython 正则表达式从点分隔字母中删除点
【发布时间】:2021-04-07 08:50:52
【问题描述】:

我想去掉单词中的点,使a.b.c.d变成abcd,但是在某些情况下:

  • 单词中应该有至少2个点,例如a.b仍然是a.b,但是a.b.c是匹配的。
  • 这应该只匹配 1 或 2 个字母。例如,a.bb.c 是匹配项(因为 abbc 各有 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

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

【问题讨论】:

    标签: python regex regex-group python-re


    【解决方案1】:

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

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


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

    为防止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 次​​li>
    • ){2,}关闭非捕获组并重复2次或更多次以匹配至少2个点
    • \b一个字边界

    Regex demo | Python demo

    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
    

    【讨论】:

      【解决方案2】:
      ^(?=(?:.*?\.){2,}.*$)[a-z]{1,2}(?:\.[a-z]{1,2})+$
      

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

      查看演示。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-13
        • 1970-01-01
        • 2020-04-24
        • 1970-01-01
        • 2013-06-22
        • 2021-07-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多