检索Python3.6处理re.sub公司()在Python3.7中具有零长度匹配

2024-10-03 02:48:09 发布

您现在位置:Python中文网/ 问答频道 /正文

在python3.7中,零长度匹配的处理已经改变。在Python3.6(及之前的版本)中考虑以下问题:

>>> import re
>>> print(re.sub('a*', 'x', 'bac'))
xbxcx
>>> print(re.sub('.*', 'x', 'bac'))
x

在python3.7中,我们得到了以下结果:

^{pr2}$

我知道这是PCRE的标准行为。此外,芬代尔()似乎总是检测到其他匹配项:

>>> for m in re.finditer('a*', 'bac'):
...     print(m.start(0), m.end(0), m.group(0))
...
0 0
1 2 a
2 2
3 3

也就是说,我对检索Python3.6的行为很感兴趣(这是用于实现sed in python)的爱好项目。在

我可以提供以下解决方案:

def sub36(regex, replacement, string):

    compiled = re.compile(regex)

    class Match(object):
        def __init__(self):
            self.prevmatch = None
        def __call__(self, match):
            try:
                if match.group(0) == '' and self.prevmatch and match.start(0) == self.prevmatch.end(0):
                    return ''
                else:
                    return re._expand(compiled, match, replacement)
            finally:
                self.prevmatch = match

    return compiled.sub(Match(), string)

它给出了:

>>> print(re.sub('a*', 'x', 'bac'))
xbxxcx
>>> print(sub36('a*', 'x', 'bac'))
xbxcx
>>> print(re.sub('.*', 'x', 'bac'))
xx
>>> print(sub36('.*', 'x', 'bac'))
x

然而,对于这些例子来说,这似乎是精心设计的。在

实现Python3.6行为的正确方法是什么re.sub公司()零长度匹配python3.7?在


Tags: inselfrereturndefmatchgroupstart
3条回答

根据3.7最新消息

The previous behavior can be restored by changing the pattern to r'.+'.

请参见“PythonAPI中的更改”下的https://docs.python.org/3/whatsnew/3.7.html。因此,解决方案似乎是修改这样一个regex;似乎没有一个标志可以传递给re来请求此行为。在

满足原始示例的PCRE(包括python3.7+)将是:

^a*|a+|(?<!a)$

https://regex101.com/r/zTpV1t/3

但是,bbaacc会被xbbxccx取代(而不是生成xbxbxcxcx的python3.6版本)a*对某些人来说仍然足够好。在

您的解决方案可能在regex egg

Regex鸡蛋介绍

This regex implementation is backwards-compatible with the standard ‘re’ module, but offers additional functionality. The re module’s behaviour with zero-width matches changed in Python 3.7, and this module will follow that behaviour when compiled for Python 3.7.


安装:

pip install regex

用法:

{{cdex}可以使用^ cdex}来编译{cdex},其中^

^{pr2}$

注:

Version can be indicated by VERSION0 or V0 flag, or (?V0) in the pattern.


资料来源:

Regex thread - issue2636
regex 2018.11.22

相关问题 更多 >