Python 正则表达式 : splitting on pattern match that is an empty string

标签 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() 来做到这一点.

最佳答案

不幸的是,split 需要一个非零宽度的匹配,但它还没有被修复,因为相当多的不正确的代码取决于当前的行为,例如使用[something]* 作为正则表达式。使用此类模式现在将生成一个 FutureWarning,而那些 never 不能拆分任何东西,从 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模块,你可以使用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'))

关于Python 正则表达式 : splitting on pattern match that is an empty string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29988595/

相关文章:

python - 除了显示之外,打印功能实际上做了什么?

python - 如何使用 python 在两列上提取给定条件的行?

html - html 样式属性的正则表达式

c - 字符串比预期的要长,并被视为多个输入

database - 我应该使用字符串表来提高数据库效率吗?

string - 如何在Emacs中大写英文字符串

python - 验证输入值 - PySimpleGUI

python - 获取所有对象 ID 的列表

Ruby 在选择 block 中使用正则表达式

python - 匹配字符串的一部分,直到它到达行尾(python 正则表达式)