Python正则表达式:拆分模式匹配,这是一个空字符串

时间:2015-05-01 14:18:51

标签: python regex string split

使用re模块,似乎我无法拆分空字符串的模式匹配:

>>> re.split(r'(?<!foo)(?=bar)', 'foobarbarbazbar')
['foobarbarbazbar']

换句话说,即使找到匹配项,如果它是空字符串,即使re.split也不能拆分字符串。

docs for 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()

来完成此操作

2 个答案:

答案 0 :(得分:8)

遗憾的是,split需要非零宽度匹配,但尚未修复,因为相当多的错误代码依赖于当前行为,例如使用{{1}作为正则表达式。使用此类模式现在将生成[something]*,那些从不可以分割任何内容,从Python 3.5开始抛出FutureWarning

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编写自己的拆分功能:

re.finditer()

如果您确定匹配仅为零宽度,则可以使用拆分的开头来获得更简单的代码:

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

答案 1 :(得分:3)

import regex
x="bazbarbarfoobar"
print regex.split(r"(?<!baz)(?=bar)",x,flags=regex.VERSION1)

您可以在此处使用regex模块。

(.+?(?<!foo))(?=bar|$)|(.+?foo)$

使用re.findall

See demo