如何使用正则表达式查找重复的非连续词?

时间:2018-12-04 19:29:27

标签: python

我需要重印一首符合特定规则的诗句。我遇到麻烦的规则是,如果某行中的单词出现次数超过一次,则重新打印该行。

例如,不会打印“我必须和简一起出去”。 而“我必须和简一起去看电影”会显示,因为该行中重复了“ 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”。

我正在尝试找出是否有一种方法可以编写代码,以便在发现行中任何单词的非连续重复项时打印行,从而可以在给定的任何行上工作。

1 个答案:

答案 0 :(得分:1)

匹配连续和非连续重复单词的常规正则表达式为

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

请参见regex demo

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

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

或者在Python re.S中使用re.DOTALLre

要使其不区分大小写,请添加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']