【问题标题】:Python 2 vs 3 Regex differencePython 2 与 3 正则表达式的区别
【发布时间】:2019-05-04 07:34:22
【问题描述】:

我有一个在 Python 2 中完美运行的正则表达式:

parts = re.split(r'\s*', re.sub(r'^\s+|\s*$', '', expression)) # split expression into 5 parts

这个正则表达式会将一个表达式分成5个部分,例如,

'a * b   =     c' will be split into ['a', '*', 'b', '=', 'c'],
'11 + 12 = 23' will be split into ['11', '+', '12', '=', '23'],
'ab   - c = d' will be split into ['ab', '-', 'c', '=', 'd'],

等等

但在 Python 3 中,这个正则表达式的工作方式完全不同,

'a * b   =     c' will be split into ['', 'a','', '*', '', 'b','', '=', '',  'c', ''],
'11 + 12 = 23' will be split into ['', '1', '1', '', '+', '', '1', '2', '', '=', '', '2', '3', ''],
'ab   - c = d' will be split into ['', 'a', 'b', '', '-', '', 'c', '', '=', '', 'd', ''],

一般来说,在 Python 3 中,part 中的每个字符都会被拆分成一个单独的部分,被移除的空格(包括不存在的前导和尾随)会变成一个空的部分('')并被添加到该部分中列表。

我认为这个 Python 3 正则表达式的行为与 Python 2 有很大的不同,谁能告诉我 Python 3 会发生如此大变化的原因,以及像 Python 2 中那样将表达式分成 5 个部分的正确正则表达式是什么?

【问题讨论】:

  • 无论如何分割一个可能为零长度的模式都是错误的。不知道 Python2 如何做到你所说的。请改用r'\s+'
  • 它的工作方式与 3.6 版中的 python2 类似,尽管它会警告非空模式匹配,但是是的,使用 split(r'^\s+',
  • @o11c 对非零长度模式进行拆分并不是“错误的”,它是一个非常有用的工具。 Python 不支持这一点的事实是最糟糕的设计决策,luckily got revised in Python 3.7.

标签: python regex python-3.x python-2.7


【解决方案1】:

在 Python 3.7 中,re.split() 添加了对零长度匹配进行拆分的功能。当您将拆分模式更改为 \s+ 而不是 \s* 时,行为将与 3.7+ 中的预期相同(并且在 Python

def parts(string)
    return re.split(r'\s+', re.sub(r'^\s+|\s*$', '', string))

测试:

>>> print(parts('a * b   =     c'))
['a', '*', 'b', '=', 'c']
>>> print(parts('ab   - c = d'))
['ab', '-', 'c', '=', 'd']
>>> print(parts('a * b   =     c'))
['a', '*', 'b', '=', 'c']
>>> print(parts('11 + 12 = 23'))
['11', '+', '12', '=', '23']

regex 模块是re 的直接替代品,它具有“V1”模式,使现有模式的行为与 Python 3.7 之前的行为相同(请参阅this answer)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 2016-11-18
    相关资源
    最近更新 更多