首页 > 解决方案 > 使用具有多个真值的 OR 使用正则表达式提取字符串它返回什么结果?

问题描述

我可以使用一些关于 str.extract 如何在 python 中使用正则表达式的解释。

例如,我有一些字符串

6/18/1985 Primary Care Doctor
In 1980, the patient was living in Naples and de
2008 partial thyroidectomy
2/6/96 sleep studyPain Treatment Pain Level

我使用以下代码提取字符串中的日期:

str.extract('((\d{1,2}[/]\d{1,2}[/]\d{2,4})|(\d{4}))')

这段代码与我原来的刺痛完美配合,并输出:

6/18/1985
1980
2008
2/6/96

但是,我的问题是,既然6/18/1985技术上将我的第二个条件(\d{4})与返回值相匹配1985,那么为什么我的代码仍然有效并返回值为6/18/1985

我认为我最大的困惑来自|(或)运算符如何在有多个真实结果的代码中工作,应该返回哪个?

有什么想法吗?提前谢谢了

标签: pythonregexpandasextract

解决方案


考虑这个正则表达式匹配

import re
>>> re.findall('(\d{1,2}[/]\d{1,2}[/]\d{2,4})|(\d{4})|([P])', "6/18/1985 2234 Primary Care Doctor")
[('6/18/1985', '', ''), ('', '2234', ''), ('', '', 'P')]
    ^^^1st group^^^      ^^^2nd group^^^  ^^^3rd group^^^

从上面的匹配中我们可以看出,由于我们在正则表达式模式中指定了 3 个匹配组,因此正则表达式引擎将尝试匹配目标字符串中的每个单独的组,如果至少有一个匹配项不匹配,则返回该组空的。在这里,从 string"6/18/1985 2234 Primary Care Doctor"中,每个捕获组都能够找到至少一个非空匹配项,因此返回该组。OR 告诉正则表达式尝试查找字符串中的每个模式以找到至少一个非空匹配项,如果是,则返回整个组。另一方面,如果我们尝试匹配此字符串中的上述模式

>>> re.findall('(\d{1,2}[/]\d{1,2}[/]\d{2,4})|(\d{4})|([P])', "6/18/1985 Primary Care Doctor")
[('6/18/1985', '', ''), ('', '', 'P')]
   ^^^1st group^^^      ^^^3rd group^^^

我们可以看到,我们没有得到第二个模式的任何匹配项,(\d{4})因为该模式在字符串中找不到单个非空匹配项(没有 4 个整数),因此只返回包含 at 的第一个和第三个模式的匹配项- 包含非空匹配的最少返回组。

在您的情况下,正则表达式始终能够在熊猫的每一行字符串中找到至少一个非空匹配项,如下所示:

>>> df = pd.Series(["6/18/1985 Primary Care Doctor", "In 1980, the patient was living in Naples and de"])
>>> df.str.extract('(\d{1,2}[/]\d{1,2}[/]\d{2,4})|(\d{4})')
           0     1
0  6/18/1985   NaN
1        NaN  1980

您可以看到第一个字符串中的第二个模式和第二个字符串中的第一个模式有 NaN 值。


推荐阅读