【问题标题】:Re module and positive look behind of variable width重新模块和可变宽度的正面观察
【发布时间】:2019-11-29 17:29:50
【问题描述】:

我是编程和 Python 的新手,所以如果这是一个明显的问题,我深表歉意。我尝试在这个网站上查看类似的问题,但解决方案似乎超出了我的能力范围。

问题:考虑以下文本:

12/19 保罗 1/20

1/20 雅各布 10/2

使用模块 re,从上面提取名称。换句话说,你的输出应该是:

['保罗','雅各布']

首先,我尝试使用积极的环顾四周。我试过了:

import re

name_regex=re.compile(r'''(
(?<=\d{1,2}/\d{1,2}\s)      #looks for one or two digits followed by a forward slash followed by one or two digits, followed by a space
.*?                        #looks for anything besides the newline in a non-greedy manner (is the non-greedy part necessary? I am not sure...)
(?=\s\d{1,2}/\d{1,2})  #looks for a space followed by one or two digits followed by a forward slash followed by one or two digits
)''', re.VERBOSE)

text=str("12/19 Paul 1/20\n1/20 Jacob 10/2")
print(name_regex.findall(text))

但是,上面会产生错误:

re.error: look-behind requires fixed-width pattern

通过阅读类似的问题,我相信这意味着环顾四周不能有可变长度(即,它们不能寻找“1 或 2 位数字”)。

但是,我该如何解决这个问题?

任何帮助将不胜感激。特别是适合像我这样的几乎完全初学者的帮助!

PS。最终,被日期包围的名字列表可能会很长。日期可以有一个或两个数字,用斜线分隔。我只是想举一个最小的工作示例。

谢谢!

【问题讨论】:

  • @Emma 谢谢,几乎成功了!我得到以下输出:['Paul', '1/20 Jacob']。所以几乎是我想要的。知道如何改进它吗?

标签: python regex regex-lookarounds regex-greedy


【解决方案1】:

如果你想在数字模式之间至少匹配一个非空白字符,你可以使用

(?<=\d{1,2}/\d{1,2}\s)\S.*?(?=\s\d{1,2}/\d{1,2})

这部分\S.*? 将匹配一个非空白字符,后跟除换行符以外的任何字符,因此它将匹配直到断言第一次出现(?=\s\d{1,2}/\d{1,2})

Python demo

注意,如果您使用 .*?,那么 match 也会返回一个空条目 ['Paul', '', 'Jacob'],请参阅 this example


您也可以使用捕获组而不是环视:

\d{1,2}/\d{1,2}\s(\S.*?)\s\d{1,2}/\d{1,2}

Regex demo

【讨论】:

  • 很好的答案!谢谢
  • @Pawel 有什么特别的理由要使用环视吗?
  • @AlexanderCécile Alexander,我不确定。我正在自学 Python,所以这是我想到的第一件事。我的思考过程如下:我想在没有日期的情况下捕获名称。因此,我希望我的计算机查找模式:“日期名称日期”并仅捕获名称。一些谷歌搜索让我阅读了有关环视的信息。但是,我不确定这是否是进行此类搜索的最佳或最有效的方法。
  • @Pawel 看起来不错,虽然我会按照 The Fourth Bird 的建议使用捕获组。
  • @Pawel 如果你以前没有听说过,我推荐这个网站regex101.com。我发现它对于任何涉及 RegEx 的事情都是无价的。
猜你喜欢
  • 2019-12-18
  • 1970-01-01
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 2016-09-25
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
相关资源
最近更新 更多