我一直坚持这个正则表达式
# Find the following keywords: sea, sear, search,
# Find all overlapping keywords
p = re.compile(r'(sea)+(r?((ch)?))')
pos = 0
while pos<len(s):
m = p.search(s,pos)
if m:
pos = m.end()
w = m.group()
g = m.groups()
#print w,g
for k in range(len(g)):
if g[k]:
w += ', '+g[k]
print w
else:
break
s ='search for searing remarks that mark whether the ark came by sea'
我也需要找到所有重叠的关键字。 但是我的尝试产生了
search, sea
search, sea, rch
search, sea, rch, ch
sear, sea
sear, sea, r
sea, sea
我应该如何处理它。我今天刚学会了。在此先感谢
预期结果: 海,灼烧,寻找第一个'搜索' 灼热应该产生灼热和海水
答案 0 :(得分:2)
您当前的正则表达式应该能够检测到sea
,sear
或search
。但是,有一个小问题:
(sea)+(r?((ch)?))
^ ^ ^
2 1 1
在我标记为1
的2个点上,您允许seach
与正则表达式匹配。由于r
和ch
都是可选的,因此可以seach
。
您允许重复sea
,这意味着seaseasear
可以匹配。嗯,这不是一场灾难,你仍然可以确定多少重复,但这很不方便。
修正了一下:
sea(r(ch)?)?
使用上面的正则表达式,由于?
是贪婪的,它会在回溯与空字符串匹配的情况之前尝试匹配。因此,搜索顺序为search
- &gt; sear
- &gt; sea
。
由于re.search
方法不允许多个匹配从同一索引开始,因此必须在单个匹配中处理它们。我想不出任何直接给出结果的方法。可能检查和推断是唯一的方法。
有很多方法可以检查匹配的内容。检查组0中字符串的长度是单向的。另一种方法是检查组2和组1中匹配的内容。
答案 1 :(得分:1)
你可能正在寻找一个后视断言。见here
您还应该将“r”和“ch”组转换为第一个捕获组中的非捕获组,如下所示(假设单词边界始终为空格,您可以轻松地概括它):
p = re.compile("(sea(?:r(?:ch)?)?) ")
如果您的关键字始终是一串前缀,那么您通过对字符串中的每个位置进行迭代来浪费时间。您只想匹配从最大到最小的前缀(即最大的前缀将首先匹配):
p = re.compile("(search|sear|sea)")
然后,您可以使用函数拆分较大的前缀。