Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何提取文本中每个可能的日期?_Python_Regex_Python 3.x_Pandas - Fatal编程技术网

Python 如何提取文本中每个可能的日期?

Python 如何提取文本中每个可能的日期?,python,regex,python-3.x,pandas,Python,Regex,Python 3.x,Pandas,我有以下文本块: “他们在跳芭蕾舞,”美国宇航局材料科学家亚当·埃里森说 这家公司看着熔炉工人倾倒玻璃 像硫磺一样的热量进入周围的空气。“天气热得要命,孩子们 2003年10月23日,玻璃很快变硬,你只能工作 他说。埃里森知道他帮了忙 开发他们正在浇注的材料,时间是2003年11月19日 品牌Gorilla玻璃,2011年10月17日出现在许多玻璃上 智能手机,因为它坚韧、纤薄,而且2000年11月19日 1098年1月41日 我想创建一个正则表达式来提取所有可能的日期格式。例如,正则表达式必须

我有以下文本块:

“他们在跳芭蕾舞,”美国宇航局材料科学家亚当·埃里森说 这家公司看着熔炉工人倾倒玻璃 像硫磺一样的热量进入周围的空气。“天气热得要命,孩子们 2003年10月23日,玻璃很快变硬,你只能工作 他说。埃里森知道他帮了忙 开发他们正在浇注的材料,时间是2003年11月19日 品牌Gorilla玻璃,2011年10月17日出现在许多玻璃上 智能手机,因为它坚韧、纤薄,而且2000年11月19日 1098年1月41日

我想创建一个正则表达式来提取所有可能的日期格式。例如,正则表达式必须提取:

23 october 2003
19 November 2003
October 17, 2011
对于上述内容,我尝试了以下方法:

((\d+).(January|February|March|April|May|June|July|August|September|October|November|December).(\d+))

但是我不知道如何匹配空格、小写和大写(
?:
),尤其是这种格式
2011年10月17日
。您知道如何获得所需的先前输出吗?

您是否明确需要月份名称

(?:[1-3][0-9]\s\w+|\w+\s[1-3][0-9]),?\s[0-9]+
所以

  • [1-3][0-9]
    日期(不完全是01-31)
  • \s\w+
    space+word
  • 单词+空格+日期
  • ,?
    可选逗号+空格
  • 一个或多个数字


我认为01-31应该是类似于
(0[1-9]|[12][0-9]|[3[01])
,但是你提到了“可能的日期”,所以2月31日就不可能了

给定该文本,您可以得到如下日期:

>>> re.findall(r'(\b(?:[1-3][0-9]\s[a-zA-Z]+\s[12][0-9]{3})|(?:[a-zA-Z]+\s[1-3][0-9],\s?[12][0-9]{3})\b)', txt)
['23 october 2003', '19 November 2003', 'October 17, 2011']

您可以尝试以下方法:

from dateutil import parser
import re

a = """“They’re doing a ballet,” says Adam Ellison, a materials scientist at the company, watching the furnace workers as the glass dumps brimstone-like heat into the surrounding air. “It’s hot as hell, the glass 23 october 2003 gets stiff very quickly, and you can only work with it for a few minutes,” he says. Ellison would know—he helped develop the material they’re pouring, which is 19 November 2003 branded Gorilla Glass and is October 17, 2011 found on many smartphones because it is tough, thin, and 19 November 200000003 lightweight 41 january 1098."""
b = re.findall(r'\S+ \S+ (?=\d{4}\b)\d{4}', a)
print b
tl = []
for c in b: 
    try:
        if parser.parse(c):
            tl.append(c)
    except:
        pass
print tl
输出:

['23 october 2003', '19 November 2003', 'October 17, 2011', '41 january 1098']
['23 october 2003', '19 November 2003', 'October 17, 2011']

虽然这不是最好的解决方案,但它是有效的:

from IPython.display import display as dp
import pandas as pd
import re

a="""“They’re doing a ballet,” says Adam Ellison, a materials scientist at the company, watching the furnace workers as the glass dumps brimstone-like heat into the surrounding air. “It’s hot as hell, sdkhfks BDR 1990  the glass 23 october 2003 gets stiff very quickly, and you can only work with it for a few minutes,” he says. Ellison would know—he helped develop the material they’re pouring, which is 19 November 2003 branded Gorilla Glass and is October 17, 2011 found on many smartphones because it is tough, thin, and 19 November 200000003 lightweight 41 january 1098. 31 february 1990 sdkhfks AB 1990. """

def foo(a):
    b = re.findall(r'\S+ \S+ (?=\d{4})\d{4}\b', a)
    tl = []
    for c in b: 
        try:
            if pd.tseries.tools.parse_time_string(c):
                tl.append(c)
        except:
            pass
    return tl

df = pd.DataFrame(data={'c1': [a, a]})
dp(df)
df['valid_dates'] = df.c1.apply(lambda x: foo(str(x)))
dp(df)
输出:

['23 october 2003', '19 November 2003', 'October 17, 2011', '41 january 1098']
['23 october 2003', '19 November 2003', 'October 17, 2011']


尝试添加
i
g
标记位置是否重要?。。。你能举个例子吗@贝加多?。。。谢谢你的评论@你能展示你现有的python代码吗?它只是正则表达式。。。我打算用熊猫:
df['text'].str.findall(r)(\d+)(一月|二月|三月|四月|五月|六月|七月|八月|九月|十月|十一月|十二月|)(\d+)。申请(“,”。加入)
@cricket 007这是个日期,所以把它放在你认为应该去的地方吧;)我会让你知道我似乎也有误报:
38 DUB 29875954
,这就是为什么我试着设置所有的月份。。。你知道如何避免误报吗?。。。因此,是的,我需要明确的月份名称。只要用您拥有的月份列表替换
\w+
,然后我尝试这样修改:
(?:[1-3][1-9]+|(一月|二月|三月|四月|五月|六月|七月|八月|九月|十月|十一月|十二月|)+|(一月|二月|三月|四月|五月|六月|七月|十月|十月|九月1243 |十月1243 |九月|[1-9]),?\s[0-9]+
[1-3][1-9]
与任何月份的第10个不匹配…如果我用该文本构造一个数据帧,并且有
pat=r'(\b(?[1-3][0-9]\s[a-zA-Z]+\s[12][0-9]{3});(?:[a-zA-Z]+\s[1-3][0-9][0-9][3})b)
`它返回与预期相同的匹配项。可能您的数据帧没有作用于一个系列?我不知道。在这里工作。Pandas的版本?这与我的正则表达式不同。但是请尝试
(?:\b[1-3][0-9]\s[a-zA-Z]+\s[12][0-9]{3}\b)|(?:\b[a-zA-Z]+\s[1-3][0-9],\s?[12][0-9]{3}\b))
尝试一个简单的正则表达式,看看是否有文本正在被处理。尝试df['text'].str.findall(r'\d+'))`另外,确保你的正则表达式是一个原始字符串'r'模式',或者你需要重新转义它。如果它不起作用,我想问一个新问题。RGEX在熊猫中没有得到太多关注。祝你好运!@tumbleweed现在检查。它更好吗?@tumbleweed但它将在2001年2月30日
失败@tumbleweed除了
2月30日
,你知道吗还必须检查闰年的有效日期。例如,
2017年2月29日
无效,但
2016年2月29日
有效。@tumbleweed是,但
parser.parse()
将为该奇怪字符串抛出错误,并且不会将其附加到
tl
中。您将获得
tl
列表中的所有有效日期。@tumbleweed在获取
tl
列表中的所有有效日期时,为什么要关心正则表达式。这不是您所需要的吗?