【问题标题】:How to use Regular Expressions to find duplicate non-consecutive words?如何使用正则表达式查找重复的非连续单词?
【发布时间】:2020-03-10 22:35:30
【问题描述】:

我需要重印符合特定规则的诗行。我遇到问题的规则是,如果该行有一个出现多次的单词,则重新打印该行。

例如,I have to go out with Jane 不会打印。而I have to go out to the movies with Jane 将打印为单词to 在行中重复。

Rules = ['']

Yip = open('poem.txt', 'r')
Lines = Yip.read().split('\n')

n = 1
for r in Rules:
i = 1
print("\nMatching rule", n)
for ln in Lines:
    if re.search(r, ln):
        print(i, end = ", ")
    i = i + 1
n = n + 1

我得到了代码'(?i)\\b([a-z]+)\\b(?:\\s+\\1\\b)+',这可以找到重复的单词,但只能连续查找。

同样,我已经到达'^(?=(.*?to){2}).*$',这是我相信我最接近的代码。它会在找到“to”的两个实例时打印上面的行,但问题是它只命中了“to”。

我正在尝试找出是否有办法编写代码,如果它发现行中任何单词的非连续重复项将打印该行,以便它可以在给定的任何行上工作。

【问题讨论】:

  • 添加示例输入和输出可以帮助用户向您展示他们的解决方案是如何工作的,并准确地关注您的需求
  • 你有理由使用正则表达式吗?您提供给 ln.split() 的计数器将实现相同的效果,而无需正则表达式的开销。

标签: python regex


【解决方案1】:

匹配连续和不连续重复词的通用正则表达式是

\b(\w+)\b(?=.*?\b\1\b)

regex demo

要使模式跨行搜索重复的单词,请确保 . 匹配换行符,例如:

 (?s)\b(\w+)\b(?=.*?\b\1\b)
 ^^^^

或者,在 Python 中使用 re.Sre.DOTALL re

要使其不区分大小写,请添加i 修饰符,或使用re.I / re.IGNORECASE

 (?si)\b(\w+)\b(?=.*?\b\1\b)
 ^^^^^

模式详情

  • \b - 字边界
  • (\w+) - 第 1 组:一个或多个单词字符(字母、数字、_
  • \b - 字边界
  • (?=.*?\b\1\b) - 与紧随其后的位置匹配的正向前瞻
    • .*? - 任何 0+ 个字符,尽可能少
  • \b\1\b - 将第 1 组值作为整个单词(我们需要在这里再次使用 \b 单词边界,因为 \1 不会“记住”(\w+) 匹配的上下文)。

Python demo:

import re
strs = ['I have to go out with Jane','I have to go out to the movies with Jane']
rx = re.compile(r'(?si)\b(\w+)\b(?=.*?\b\1\b)')
for s in strs:
    print(s, "=>", rx.findall(s))

输出:

I have to go out with Jane => []
I have to go out to the movies with Jane => ['to']

【讨论】:

    猜你喜欢
    • 2012-02-27
    • 2013-12-29
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    相关资源
    最近更新 更多