匹配带有可选前瞻的正则表达式

Posted

技术标签:

【中文标题】匹配带有可选前瞻的正则表达式【英文标题】:match a regular expression with optional lookahead 【发布时间】:2016-01-10 12:19:51 【问题描述】:

我有以下字符串:

NAME John Nash FROM California

NAME John Nash

我想要一个能够为两个字符串提取“John Nash”的正则表达式。

这是我尝试过的

"NAME(.*)(?:FROM)"
"NAME(.*)(?:FROM)?"
"NAME(.*?)(?:FROM)?"

但这些都不适用于两个字符串。

【问题讨论】:

这两行都是完整的吗? 【参考方案1】:

您可以在FROM 和锚点$ 之间使用逻辑或:

NAME(.*)(?:FROM|$)

查看演示https://regex101.com/r/rR3gA0/1

在这种情况下,在名称之后,它将匹配 FROM 或字符串的结尾。但在您的正则表达式中,因为您在第一种情况下将 FROM 设为可选,它将匹配名称之后的其余字符串。

如果您想使用更通用的正则表达式,您最好根据您的姓名可能性形状创建您的正则表达式,例如,如果您确定您的姓名是从 2 个单词创建的,您可以使用以下正则表达式:

NAME\s(\w+\s\w+)

演示https://regex101.com/r/kV2eB9/2

【讨论】:

【参考方案2】:
 r'^\w+\s+(\w+\s+\w+) - word at start of string
 follows by one or more spaces and
 two words and at least one space between them

with open('data', 'r') as f:
    for line in f:
      mo =   re.search(r'^\w+\s+(\w+\s+\w+)',line)
      if mo:
        print(mo.group(1))

John Nash
John Nash

【讨论】:

【参考方案3】:

将字符串的第二部分设为可选(?: FROM.*?)?,即:

NAME (.*?)(?: FROM.*?)?$

MATCH 1
1.  [5-14]  `John Nash`
MATCH 2
1.  [37-46] `John Nash`
MATCH 3
1.  [53-66] `John Doe Nash`

正则表达式演示https://regex101.com/r/bL7kI2/2

【讨论】:

【参考方案4】:

你可以不用正则表达式:

>>> myStr = "NAME John Nash FROM California"
>>> myStr.split("FROM")[0].replace("NAME","").strip()
'John Nash'

【讨论】:

以上是关于匹配带有可选前瞻的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

带有可选匹配组的正则表达式

javascript 正则表达式之分组与前瞻匹配详解

正则表达式前瞻丢弃匹配

JS 正则表达式否定匹配(正向前瞻)

Prometheus(公制)使用逆正则表达式匹配/负前瞻重新标记配置

正则表达式前瞻(?=)后顾(?<)负前缀(?!)负后顾(?<!)