我正在尝试匹配/索引填充了空白的字符串。这可以用正则表达式完成吗?以下是我目前的解决方案:
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
只是感觉很乱......
答案 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
可以紧凑地存储间隙编码。