【问题标题】:Whitespace at the end of line is not ignored by python regexpython 正则表达式不会忽略行尾的空格
【发布时间】:2016-08-25 19:48:23
【问题描述】:

前面的空格被忽略,但后面的空格不在下面的正则表达式代码中。它只是一个"Name = Value" 字符串,但带有空格。我以为捕获后的\s* 会忽略空格。

import re
line = "  Name =  Peppa Pig  "
match = re.search(r"\s*(Name)\s*=\s*(.+)\s*", line)
print(match.groups())
>>>('Name', 'Peppa Pig   ')  # Why extra spaces after Pig!

我错过了什么?

【问题讨论】:

  • 不管什么问题都可以使用match = match.strip()删除前导和尾随空格。
  • 查看我对正在发生的事情的解释,以及regex+strip based solution below
  • @OhadEytan - 是的,我当然可以在 python 中剥离,但我想了解正则表达式的方式,因为该行可能有多个“名称 = 值”对。即在线上可能会有更多捕获
  • 可以理解,这就是为什么我以“不管问题”开头的原因

标签: python regex


【解决方案1】:

由于.+ 的贪婪本性,您会得到尾随空格。

您可以使用此正则表达式来正确捕获您的值:

>>> re.search(r"\s*(Name)\s*=\s*(.+?)\s*$", line).groups()
('Name', 'Peppa Pig')

\s*$ 确保我们在末尾尾随空格之前捕获值。

【讨论】:

  • 作为一个局外人,可能在某些时候有过这样的问题..在(.+?) 中添加的? 做了什么?
  • .+? 使其成为与贪婪的.+ 相比的懒惰匹配
  • 但是懒惰的量词在性能上输给了贪婪的量词(见卡西米尔的回答),因为最后有很多空格。
  • 另外,让 regex 完成它的繁重工作,让 Python 完成修剪工作。两全其美:)
  • @anubhava - 不错,但我更喜欢卡西米尔的回答
【解决方案2】:

最后一个.+ 抓取整个行的其余部分(因为. 匹配除换行符以外的任何字符),然后开始回溯,检查后续子模式是否应该匹配。由于后面的子模式是\s*,它可以匹配一个空字符串(它匹配0+个空格),这个模式成功匹配到字符串的末尾,并返回一个带有尾随空格的有效匹配。

your regex demo(特别注意第15步):

您可以让 Python 在列表解析中执行 strip 工作,并将正则表达式简化为 (Name)\s*=(.+)

import re
line = "  Name =  Peppa Pig  "
match = [(x,y.strip()) for x,y in re.findall(r"(Name)\s*=(.+)", line)]
print(match)

Python demo

【讨论】:

    【解决方案3】:

    而不是使用(.+)\s* (其中\s* 是无用的,因为“零个或多个空格”不是贪婪量词.+ 之后的约束,就像什么都不写) em>,你可以使用(.*\S),它会自动修剪最后一个非空白字符\S之后的字符串。

    match = re.search(r"\b(Name)\s*=\s*(.*\S)", line)
    

    问题:是否真的需要捕获已知的“名称”文字字符串?

    【讨论】:

      猜你喜欢
      • 2014-05-20
      • 1970-01-01
      • 2021-09-13
      • 2020-08-06
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      相关资源
      最近更新 更多