提取以“st”、“nd”、“rd”、“th”结尾的日期,同时使用 RegEx 将日期与月份交换

Posted

技术标签:

【中文标题】提取以“st”、“nd”、“rd”、“th”结尾的日期,同时使用 RegEx 将日期与月份交换【英文标题】:Extractall for the dates ending with 'st','nd', 'rd','th' while swapping days with months using RegEx 【发布时间】:2020-11-30 07:06:21 【问题描述】:

我在 pandas 数据框列的文本中获得了这些日期。

import pandas as pd
sr = pd.Series(['text Mar 20, 2009 text', 'text March 20, 2009 text', 'text 20 Mar. 2009 text', 'text Sep 2010 text','text Mar 20th, 2009 text ','text Mar 21st, 2009 text'])

当我使用正则表达式时,我明白了。

a=sr.str.extractall(r'((?P<day>(?:\d2 )?(?P<month>(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z,.]*)) (?:\d2[-/th|st|nd|rd\s]*[,.]* )?(?P<year>\d4))')


       all              day     month  year
match               
0   0   Mar 20, 2009    Mar      Mar    2009
1   0   March 20, 2009  March    March  2009
2   0   20 Mar. 2009    20 Mar.  Mar.   2009
3   0   Sep 2010        Sep      Sep    2010
4   0   Mar 20th, 2009  Mar      Mar    2009
5   0   Mar 21st, 2009  Mar      Mar    2009

如何将日期(20、20、21...)放入日期列?

【问题讨论】:

【参考方案1】:

使用 pandas 的一个解决方案(为什么要重新发明***?):

    import pandas as pd
    df = sr.to_frame(name='all')
    df['all'] = pd.to_datetime(df['all'])
    df['day'] = df['all'].dt.day
    df['month'] = df['all'].dt.strftime('%b')
    df['year'] = df['all'].dt.year

输出:

         all  day month  year
0 2009-03-20   20   Mar  2009
1 2009-03-20   20   Mar  2009
2 2009-03-20   20   Mar  2009
3 2010-09-01    1   Sep  2010
4 2009-03-20   20   Mar  2009
5 2009-03-21   21   Mar  2009

【讨论】:

我改变了问题.. 抱歉有任何混淆。这些字符串之一可以是这样的 ''see above and APS eval of 26 May 1982 Social History Marital Status: Single\n' 。无论如何,您的解决方案会有所帮助,即使它不完全符合我的想法! 我希望获得有关如何使用正则表达式获得相同结果的建议。【参考方案2】:

也许另一种解决方案是使用 PyPi regex module 和分支重置组 (?| 来匹配日期和月份。

没有命名组的模式:

\b((?|(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z,.]*(?: (\d2(?:th|st|nd|rd)?)?[,.])?|(\d2) (?:(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z,.]*)?) (\d4))

Regex demo

import pandas as pd
import regex

pattern = r"\b(?P<all>(?|(?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z,.]*(?: (?P<day>\d2(?:th|st|nd|rd)?)?[,.])?|(?P<day>\d2) (?:(?P<month>Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z,.]*)?) (?P<year>\d4))"

items = [
    'text Mar 20, 2009 text',
    'text March 20, 2009 text',
    'text 20 Mar. 2009 text',
    'text Sep 2010 text',
    'text Mar 20th, 2009 text ',
    'text Mar 21st, 2009 text'
]
res = map(lambda x: regex.findall(pattern, x)[0], items)
df = pd.DataFrame(res)
df.columns = ['all', 'month', 'day', 'year']
print(df)

输出

              all month   day  year
0    Mar 20, 2009   Mar    20  2009
1  March 20, 2009   Mar    20  2009
2    20 Mar. 2009   Mar    20  2009
3        Sep 2010   Sep        2010
4  Mar 20th, 2009   Mar  20th  2009
5  Mar 21st, 2009   Mar  21st  2009

【讨论】:

很高兴你又来了,因为我已经从你那里学到了比为期一周的 coursera 的“应用文本挖掘”课程更多的东西。 我对数据帧没有太多经验,但我阅读了一些帖子并尝试了几种获取数据的方法。也许会有一个更容易/更好的答案来获取数据,但我认为您可以使用/重用模式的一部分来匹配日期。 是的.. 我想我更喜欢日列作为 '20,20,20..21'。没有结尾。 它不喜欢'?|'在 \b(?P(?| ,引发错误:未知扩展 ?| 在位置 4。您所指的分支重置...我有 Python 3.6.5。 你安装了正则表达式 pypi 模块吗?

以上是关于提取以“st”、“nd”、“rd”、“th”结尾的日期,同时使用 RegEx 将日期与月份交换的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:移动到上一个屏幕(2nd)并仅删除上一个屏幕(2nd 3rd 4th),而不是所有屏幕(1st 2nd 3rd 4th)

通过python将带有'th''st''rd''nd'的日期字符串转换为日期格式

PHP 将(th,st,nd,rd,th)添加到数字的末尾

PHP 添加st,nd,rd,th到天:D

PHP st,nd,rd,th to Number

Python练习1