如何从python中的字符串中提取月份和年份?

时间:2020-05-30 23:55:27

标签: python regex pandas datetime nlp

输入文本

text = "Wipro Limited | Hyderabad, IN                Dec 2017 – Present
Project Analyst 

Infosys | Delhi, IN                Apr 2017 – Nov 2017 
Software Developer 

HCL Technologies | Hyderabad, IN                Jun 2016 – Mar 2017 
Software Engineer  
"

我已经为此编写了代码,但是它在列表中显示每个提取的单词,并且无法执行任何操作。

regex = re.compile('(?P<month>[a-zA-Z]+)\s+(?P<year>\d{4})\s+\–\s+(?P<month1>[a-zA-Z]+)\s+(?P<year1>\d{4})')
mat = re.findall(regex, text)
mat

查看代码:https://regex101.com/r/mMlgYp/1。 我希望像下面的输出预览日期并加以区别,然后计算总体验: 现在或截止日期应考虑当前月份和年份。

import time
Present = time.strftime("%m-%Y")
Present 
# output: '05-2020'
#Desired output
Extracted dates: 
[('Dec 2017 - Present'),
 ('Apr 2017 - Nov 2017'),
 ('Jun 2016 - Mar 2017')]# and so on ...should display all the search results 

First experience: 1.9 years 
second experience: 8 months
third experience: 7 months
# and so on ...should display all the search results 
Total experience: 3.4 years

请帮助我解决这个问题,我是lang和NLP,正则表达式方面的新手。

2 个答案:

答案 0 :(得分:4)

您可能最终希望在数据框中使用它,因为您已将其标记为熊猫(请参见Andrej's answer),但是无论哪种方式,您都可以使用内插法从字符串中解析日期:

fr"(?i)((?:{months}) *\d{{4}}) *(?:-|–) *(present|(?:{months}) *\d{{4}})"

{months}是所有可能月份名称和缩写的交替组。

import calendar
import re
from datetime import datetime
from dateutil.relativedelta import relativedelta

text = """Wipro Limited | Hyderabad, IN                Dec 2017 – Present
Project Analyst 

Infosys | Delhi, IN                Apr 2017 – Nov 2017 
Software Developer 

HCL Technologies | Hyderabad, IN                Jun 2016 – Mar 2017 
Software Engineer  
"""

def parse_date(x, fmts=("%b %Y", "%B %Y")):
    for fmt in fmts:
        try:
            return datetime.strptime(x, fmt)
        except ValueError:
            pass

months = "|".join(calendar.month_abbr[1:] + calendar.month_name[1:])
pattern = fr"(?i)((?:{months}) *\d{{4}}) *(?:-|–) *(present|(?:{months}) *\d{{4}})"
total_experience = None

for start, end in re.findall(pattern, text):
    if end.lower() == "present":
        today = datetime.today()
        end = f"{calendar.month_abbr[today.month]} {today.year}"

    duration = relativedelta(parse_date(end), parse_date(start))

    if total_experience:
        total_experience += duration
    else: 
        total_experience = duration

    print(f"{start}-{end} ({duration.years} years, {duration.months} months)")

if total_experience:
    print(f"total experience:  {total_experience.years} years, {total_experience.months} months")
else:
    print("couldn't parse text")

输出:

Dec 2017-May 2020 (2 years, 5 months)
Apr 2017-Nov 2017 (0 years, 7 months)
Jun 2016-Mar 2017 (0 years, 9 months)
total experience:  3 years, 9 months

答案 1 :(得分:3)

import re
import numpy as np
import pandas as pd

text = '''Wipro Limited | Hyderabad, IN                Dec 2017 – Present
Project Analyst

Infosys | Delhi, IN                Apr 2017 – Nov 2017
Software Developer

HCL Technologies | Hyderabad, IN                Jun 2016 – Mar 2017
Software Engineer
'''

def pretty_format(monthts):
    return f'{monthts/12:.1f} years' if monthts > 11 else f'{monthts:.1f} months'

data = []
for employer, d1, d2 in re.findall(r'(.*?)\s*\|.*([A-Z][a-z]{2} [12]\d{3}) – (?:([A-Z][a-z]{2} [12]\d{3})|Present)', text):
    data.append({'Employer': employer, 'Begin': d1, 'End': d2 or np.nan})

df = pd.DataFrame(data)
df['Begin'] = pd.to_datetime(df['Begin'])
df['End'] = pd.to_datetime(df['End'])

df['Experience'] = ((df['End'].fillna(pd.to_datetime('now')) - df['Begin']) / np.timedelta64(1, 'M')).apply(pretty_format)
print(df)

total = np.sum(df['End'].fillna(pd.to_datetime('now')) - df['Begin']) / np.timedelta64(1, 'M')
print()
print(f'Total experience = {pretty_format(total)}')

打印:

           Employer      Begin        End  Experience
0     Wipro Limited 2017-12-01        NaT   2.5 years
1           Infosys 2017-04-01 2017-11-01  7.0 months
2  HCL Technologies 2016-06-01 2017-03-01  9.0 months

Total experience = 3.8 years