匹配/索引字符串填充随机间隙

时间:2018-04-26 17:04:05

标签: python python-3.x

我正在尝试匹配/索引填充了空白的字符串。这可以用正则表达式完成吗?以下是我目前的解决方案:

test = 'abcd---efghi-j-k-l---mnopq-r--st-uvw-x-yz'

def match_gaps(match_string, match_target):
    ms = match_string.replace('-','').index(match_target)+1
    for c in range(len(match_string)):
        if match_string[c] != '-':
            ms -= 1
        if ms == 0:
            endp = ms
            while len(match_string[c:endp].replace('-','')) < len(match_target):
                endp += 1
            return(match_string[c:endp])

print(match_gaps(test, 'klmno'))
output: k-l---mno

只是感觉很乱......

2 个答案:

答案 0 :(得分:2)

如果我理解你正在尝试做什么,你想在匹配中的每个地方允许破折号,但在输出中保留它们。

让我们这样做:

import re

test = 'abcd---efghi-j-k-l---mnopq-r--st-uvw-x-yz'

def match_gaps(match_string, match_target):
    chars = [re.escape(c) for c in match_target]  # allow special-chars
    regex = re.compile('-*'.join(chars))  # allow dashes between chars
    return regex.findall(match_string)

print(match_gaps(test, 'klmno'))
  

[ 'K-L --- MNO']

您可能需要进行一些小的调整,以便输出完全符合您的要求,但这个想法是相同的。唯一有点棘手的部分是re.escape(对你来说甚至可能都不需要)。

答案 1 :(得分:1)

我有一个没有使用RE的解决方案。

想法是删除连字符,但记住插入它们的位置,然后进行常规字符串搜索。然后将连字符插入匹配项中。

'abcd---efghi-j-k-l---mnopq-r--st-uvw-x-yz'

会变成:

>>> idx, ss = zip(*(p for p in enumerate('abcd---efghi-j-k-l---mnopq-r--st-uvw-x-yz') if p[1] != '-'))
>>> idx
(0, 1, 2, 3, 7, 8, 9, 10, 11, 13, 15, 17, 21, 22, 23, 24, 25, 27, 30, 31, 33, 34, 35, 37, 39, 40)
>>> ''.join(ss)
'abcdefghijklmnopqrstuvwxyz'

然后找到子串:

>>> q = 'klmno'
>>> off = ''.join(ss).find(q)
>>> idx[off:off+len(q)]
(15, 17, 21, 22, 23)

通过以下方式重建它:

>>> a = ['-']*(idx[off+len(q)]-idx[off])
>>> a
['-', '-', '-', '-', '-', '-', '-', '-', '-']
>>> for i, c in zip([i - idx[off] for i in idx[off:off+len(q)]], q):
...     a[i] = c
... 
>>> ''.join(a)
'k-l---mno'

我确信上面的代码可以改进,但想法就在那里。

请注意,idx可以紧凑地存储间隙编码。