可变宽度的 Re 模块和正向后视

Re module and positive look behind of variable width

我是编程新手并且 Python,如果这是一个显而易见的问题,我深表歉意。我试着在这个网站上查看类似的问题,但解决方案似乎超出了我的范围。

问题:考虑以下文字:

12/19保罗1/20

1/20 雅各布 10/2

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

['Paul', 'Jacob']

首先,我尝试使用正面环顾四周。我试过了:

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。最终,被日期包围的名字列表可能会很长。日期可以有一位或两位数字,用斜杠分隔。我只是想举一个最小的工作示例。

谢谢!

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

(?<=\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

注意如果你使用.*?那么匹配也会return一个空条目['Paul', '', 'Jacob'],见this example .


您也可以使用捕获组而不是环顾四周:

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

Regex demo