当前位置: 首页 > 面试题库 >

Python正则表达式:拆分为空字符串的模式匹配

庄星汉
2023-03-14
问题内容

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

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

换句话说,即使找到匹配项,即使它是空字符串,re.split也无法拆分该字符串。

的文档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而那些
永远 无法拆分的模式会ValueError从Python 3.5开始抛出:

>>> 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模块,则可以使用以下代码编写自己的split函数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'))

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

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正则表达式字符串拆分: 但这在返回的列表中给了我两个额外的空字符串: 如何仅获取两个时间戳信息?即我想要: 问题答案: 不要使用,使用正则表达式/对象的方法。 您甚至可以命名捕获组并在字典中检索它们,尽管您使用的不是。(这种情况下的regex模式将类似于)

  • 问题内容: 我在尝试将我的javascript regex经验转移到Python时遇到了麻烦。 我只是想让它工作: …但是它打印无。如果我做: 它匹配…默认情况下是否匹配字符串的开头?当匹配时,如何使用结果? 我如何进行第一场比赛?是否有比python网站提供的文档更好的文档? 问题答案: 隐式添加到您的正则表达式的开头。换句话说,它仅在字符串的开头匹配。 将在所有位置重试。 一般来说,建议您在需

  • 问题内容: 我想解决这个问题。 逗号:分割条款 双引号:字符串值(忽略特殊字符) 数组 例如: 输入: 预期输出: 但是我无法获得超越结果。 我写了下面的代码: 我的输出是: 我需要更改以获得预期的输出?我应该坚持使用正则表达式还是其他解决方案更灵活,更易于维护? 问题答案: 这个正则表达式可以达到目的: 它的工作原理是在逗号后添加一个用于匹配成对的方括号的预读-如果您 位于 方括号内,那么您当然

  • 问题内容: 我有一个字符串,需要根据出现的“,”(逗号)进行拆分,但是需要忽略在一对括号内出现的任何字符串。例如, 应拆分为 问题答案: 对于非嵌套 嵌套 (括号内的括号)

  • 我有一个表格形式的命令输出。我正在解析结果文件的输出并将其存储在字符串中。一行中的每个元素由一个或多个空格字符分隔,因此我使用正则表达式匹配1个或多个空格并拆分它。但是,在每个元素之间插入一个空格: 还有更好的方法吗? 每次拆分后,str2都会附加到列表中。

  • 问题内容: 在Swift中,查看字符串是否与模式匹配的简单方法是什么? 伪代码示例: (我已阅读斯威夫特文档并没有看到一个正则表达式的能力。我读过有关增加一个新的运营商是一个好主意,但不是我想,因为这是一个教学项目。我已经尝试了更复杂的,但收到错误:“字符串”没有成员“ rangeOfString”。我正在寻找一种Swift解决方案,即未键入NSRegularExpression。我不需要对匹配结