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

时间:2015-06-09 16:42:59

标签: python regex split

在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)

2 个答案:

答案 0 :(得分:0)

我发布这个作为答案主要是为了在将来有人偶然发现问题的情况下回答这个问题,因为我已经设法达到了预期的行为,尽管可能不是以非常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']]]

在这一点上,我可能会开始考虑使用正则表达式来找到要分割的单词以及以“愚蠢的方式”进行分割。只检查范围位置中的字符是否相等char。无论如何,任何评论非常赞赏。

答案 1 :(得分:-1)

编辑:修正。

简单的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']]