如何从 Python 中的文本中提取 2d 年份?

How to extract 2d year from text in Python?

我试图从 Pandas DataFrame 的一列中的短文本中提取出生年份和死亡年份:

firstname lastname (1937-2015)

我用这个代码得到了第一年:

data = re.findall(r'\d+', txt)
if len(data) > 0 :
    data = float(data[0])
    if data >= 1800 and data <= 2021 :
        return data
return None

但我无法从文本中提取第二年。 例如,当我将 data[0] 更改为 data[1] 时,出现错误消息“list index out of range”

您可以定义2个捕获组并检查它们

df = pd.DataFrame(
    {'txt': ['firstname lastname (1937-2015)', 'firstname lastname (1780-1820)',
             'firstname lastname (1945-?)', 'firstname lastname (1980-2022)']})

df[['birth', 'death']] = df['txt'].str.extract(r'(\d+)-(\d+|\?)').replace({'?': None}).astype(float). \
    applymap(lambda x: x if 1800 <= x <= 2021 else None)
print(df)

输出:

                              txt   birth   death
0  firstname lastname (1937-2015)  1937.0  2015.0
1  firstname lastname (1780-1820)     NaN  1820.0
2     firstname lastname (1945-?)  1945.0     NaN
3  firstname lastname (1980-2022)  1980.0     NaN

使用 Series.str.extract 提取 Pandas 中第二年(从 1800 到 2099)的通用正则表达式解决方案,您可以利用

import pandas as pd
df = pd.DataFrame({'col':['firstname lastname (1937-2015)']})
yr = r'(?:1[89][0-9]{2}|20[01][0-9]|202[01])'
df['second_year'] = df['col'].str.extract(fr'(?s)(?<!\d){yr}(?!\d).*?({yr})(?!\d)')
# => df['second_year']
#   0    2015
#   Name: second_year, dtype: object

参见regex demo详情:

  • (?s) - . 现在跨行匹配
  • (?<!\d) - 左侧数字边界
  • (?:1[89][0-9]{2}|20[01][0-9]|202[01]) - 从 1800 年到 2021 年
  • (?!\d) - 右手数字边界
  • .*? - 任何文本,尽可能少的字符
  • (1[89][0-9]{2}|20[01][0-9]|202[01]) - 第 1 组(Series.str.extract 的实际 return 结果):1800 到 2021
  • (?!\d) - 右手数字边界

在这个具体案例中,一个简单的

df['second_year'] = df['col'].str.extract(r'.*-(\d{4})')

就足够了:任何文本(尽可能多的字符而不是换行符),然后是 - 和捕获到第 1 组的四位数字。

参见 this regex demo

使用正则表达式查找从和到子短语的年份,然后拆分它并为第二年编制索引。您可以在数据框中使用它申请分配给列

txt="firstname lastname (1937-2015)"
pattern='(\d{4}\-\d{4})+'

matches=re.findall(pattern,txt)
print(matches[0].split('-')[1])

输出

2015