我需要重印一首符合特定规则的诗句。我遇到麻烦的规则是,如果某行中的单词出现次数超过一次,则重新打印该行。
例如,不会打印“我必须和简一起出去”。 而“我必须和简一起去看电影”会显示,因为该行中重复了“ 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”。
我正在尝试找出是否有一种方法可以编写代码,以便在发现行中任何单词的非连续重复项时打印行,从而可以在给定的任何行上工作。
答案 0 :(得分:1)
匹配连续和非连续重复单词的常规正则表达式为
\b(\w+)\b(?=.*?\b\1\b)
请参见regex demo
要使模式搜索跨行的重复单词,请确保.
与换行符匹配,例如:
(?s)\b(\w+)\b(?=.*?\b\1\b)
^^^^
或者在Python re.S
中使用re.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+)
匹配的上下文) 。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']