[英]Python regex: splitting on pattern match that is an empty string
使用re
模塊,看來我無法拆分為空字符串的模式匹配:
>>> re.split(r'(?<!foo)(?=bar)', 'foobarbarbazbar')
['foobarbarbazbar']
換句話說,即使找到匹配項,即使它是空字符串,即使re.split
也無法拆分字符串。
對於這種特殊情況,很容易找到“解決方法”:
>>> re.sub(r'(?<!foo)(?=bar)', 'qux', 'foobarbarbazbar').split('qux')
['foobar', 'barbaz', 'bar']
但這是一種容易出錯的方法,因為這樣我就必須提防已經包含要分割的子字符串的字符串:
>>> re.sub(r'(?<!foo)(?=bar)', 'qux', 'foobarbarquxbar').split('qux')
['foobar', 'bar', '', 'bar']
有沒有更好的方法可以通過re
模塊拆分空模式匹配? 此外,為什么re.split
不允許我這樣做? 我知道使用正則表達式的其他拆分算法是可行的。 例如,我可以使用JavaScript的內置String.prototype.split()
做到這一點。
不幸的是, split
需要一個非零寬度的匹配,但尚未解決,因為相當多的不正確代碼取決於當前行為,例如使用[something]*
作為正則表達式。 現在,使用此類模式將生成FutureWarning
而那些永遠無法拆分的模式將從Python 3.5開始拋出ValueError
:
>>> re.split(r'(?<!foo)(?=bar)', 'foobarbarbazbar')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/re.py", line 212, in split
return _compile(pattern, flags).split(string, maxsplit)
ValueError: split() requires a non-empty pattern match.
這個想法是在警告一段時間后,可以更改行為,以便您的正則表達式可以再次使用。
如果您不能使用regex
模塊, regex
可以使用re.finditer()
編寫自己的split函數:
def megasplit(pattern, string):
splits = list((m.start(), m.end()) for m in re.finditer(pattern, string))
starts = [0] + [i[1] for i in splits]
ends = [i[0] for i in splits] + [len(string)]
return [string[start:end] for start, end in zip(starts, ends)]
print(megasplit(r'(?<!foo)(?=bar)', 'foobarbarbazbar'))
print(megasplit(r'o', 'foobarbarbazbar'))
如果您確定匹配項僅為零寬度,則可以使用分割的開頭來獲得更簡單的代碼:
import re
def zerowidthsplit(pattern, string):
splits = list(m.start() for m in re.finditer(pattern, string))
starts = [0] + splits
ends = splits + [ len(string) ]
return [string[start:end] for start, end in zip(starts, ends)]
print(zerowidthsplit(r'(?<!foo)(?=bar)', 'foobarbarbazbar'))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.