Python,使用正则表达式在具有重叠匹配的中间字符上拆分字符串

Python, splitting strings on middle characters with overlapping matches using regex

在 Python 中,我使用正则表达式从字典中检索显示特定模式的字符串,例如具有一些重复字符而不是特定字符和另一个重复部分(例如 ^(\w{0,2})o(\w{0,2})$).

这按预期工作,但现在我想使用中心字符作为分隔符将字符串拆分为两个子字符串(最终一个可能为空)。我遇到的问题源于字符串内多个重叠匹配的可能性(例如,我想使用前面的正则表达式以两种不同的方式拆分字符串 room(r, om)(ro, m))。

re.search().groups()re.findall() 都没有解决这个问题,re 模块上的 docs 似乎指出方法不会返回重叠匹配。

这是显示不良行为的片段:

import re
dictionary = ('room', 'door', 'window', 'desk', 'for')
regex = re.compile('^(\w{0,2})o(\w{0,2})$')
halves = []
for word in dictionary:
    matches = regex.findall(word) 
    if matches:
        halves.append(matches)

编辑:已修复。

简单的 while 循环行得通吗?

你想要的是re.search然后循环1次: https://docs.python.org/2/library/re.html

>>> dictionary = ('room', 'door', 'window', 'desk', 'for')
>>> regex = re.compile('(\w{0,2})o(\w{0,2})')
>>> halves = []
>>> for word in dictionary:
>>>     start = 0
>>>     while start < len(word):
>>>         match = regex.search(word, start)
>>>         if match:
>>>             start = match.start() + 1
>>>             halves.append([match.group(1), match.group(2)])
>>>         else:
>>>            # no matches left
>>>            break

>>> print halves
[['ro', 'm'], ['o', 'm'], ['', 'm'], ['do', 'r'], ['o', 'r'], ['', 'r'], ['nd', 'w'], ['d', 'w'], ['', 'w'], ['f', 'r'], ['', 'r']]

我将此作为答案发布主要是为了防止将来有人在这里跌跌撞撞地回答问题,并且由于我已经设法达到了预期的行为,尽管可能不是非常pythonic的方式,这作为其他人的起点可能很有用。关于如何改进此答案的一些说明(即非常欢迎 "pythonic" 或更高效)。

获取一定范围内长度的单词和一定范围位置的字符的所有可能拆分的唯一方法,使用"legal"位置中的字符作为分隔符,都使用re 和新的 regex 模块涉及使用多个正则表达式。此代码段允许在运行时创建一个适当的正则表达式,知道单词的长度范围、要查找的字符以及此类字符的可能位置范围。

dictionary = ('room', 'roam', 'flow', 'door', 'window', 
              'desk', 'for', 'fo', 'foo', 'of', 'sorrow')
char = 'o'
word_len = (3, 6)
char_pos = (2, 3)
regex_str = '(?=^\w{'+str(word_len[0])+','+str(word_len[1])+'}$)(?=\w{'
             +str(char_pos[0]-1)+','+str(char_pos[1]-1)+'}'+char+')'
halves = []
for word in dictionary:
    matches = re.match(regex_str, word)
    if matches:
        matched_halves = []
        for pos in xrange(char_pos[0]-1, char_pos[1]):
            split_regex_str = '(?<=^\w{'+str(pos)+'})'+char
            split_word =re.split(split_regex_str, word)
            if len(split_word) == 2:
                matched_halves.append(split_word)
        halves.append(matched_halves)

输出为:

[[['r', 'om'], ['ro', 'm']], [['r', 'am']], [['fl', 'w']], [['d', 'or'], ['do', 'r']], [['f', 'r']], [['f', 'o'], ['fo', '']], [['s', 'rrow']]]

在这一点上,我可能会开始考虑使用正则表达式来找到要拆分的单词,而在 'dumb way' 中进行拆分只是检查范围位置中的字符是否相等 char.总之,任何评论都非常赞赏。