Python正则表达式重叠问题被困

时间:2013-09-18 06:49:10

标签: python regex

我一直坚持这个正则表达式

# 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

我应该如何处理它。我今天刚学会了。在此先感谢

预期结果:     海,灼烧,寻找第一个'搜索'     灼热应该产生灼热和海水

2 个答案:

答案 0 :(得分:2)

您当前的正则表达式应该能够检测到seasearsearch。但是,有一个小问题:

(sea)+(r?((ch)?))
     ^  ^     ^
     2  1     1

在我标记为1的2个点上,您允许seach与正则表达式匹配。由于rch都是可选的,因此可以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)")

然后,您可以使用函数拆分较大的前缀。