在Openrefine中匹配不同的日期

时间:2017-05-14 11:49:08

标签: regex date openrefine

我正在尝试使用OpenRefine 2.6中的value.match命令将列中显示的信息拆分为(至少)2列。 然而,这些数据非常混乱 我有时候会有完整的约会:

May 30, 1949

有时候,完整日期会与其他日期和属性结合使用:

May 30, 1949, published 1979
May 30, 1949 and 1951, published 1979
May 30, 1949, printed 1980
May 30, 1949, print executed 1988
May 30, 1949, prints executed 1988
published 1940

有时你有时间:

1905-051905-1906

有时只有一年

1905

有时是属性的年份

August or September 1908

似乎没有遵循任何特定架构或订单 我想提取(至少)ca开始和结束日期年份,以便有两列:

-----------------------  
|start_date | end_date|  
|1905       | 1906    |   
-----------------------  

没有其余的属性。

我可以找到使用
的最后日期 value.match(/.*(\d{4}).*?/)[0]
和第一个用 value.match(/.*^(\d{4}).*?/)[0]
但是我对这两个公式有些麻烦 后者在以下情况下无法匹配:
May 30, 1949 and 1951, published 1979
而在以下情况下:
Paris, winter 1911-12 后一个公式不匹配任何东西,前一个公式匹配1911

任何人都知道如何解决问题? 我需要一个解决方案,将第一个日期作为start_date,将最终日期作为end_date,或更好(不知道是否可能)最早的日期为start_date,最新日期为end_date。 此外,我很高兴有一些关于如何提取其他信息的线索,例如 如果文本中存在已发布已打印已执行 - >将日期复制到新列名“执行”。 应该像创建一个新列 if(value.match("string1|string2|string3" + (\d{4}), "perform the operation", do nothing)

2 个答案:

答案 0 :(得分:1)

value.match()是一个非常有用但有时很棘手的功能。要从文本中提取模式,我更喜欢使用Python / Jython的正则表达式:

import re

pattern = re.compile(r"\d{4}")

return pattern.findall(value)

从那里,您可以创建一个连接所有年份的字符串:

return ",".join(pattern.findall(value))

或者只选择第一个:

return pattern.findall(value)[0]

或者最后一次:

return pattern.findall(value)[-1]

您的子问题也是如此:

import re

pattern = re.compile(r"(published|printed|executed)\s+(\d+)")

return pattern.findall(value)[0][1]

或者:

import re

pattern = re.compile(r"(published|printed|executed)\s+(\d+)")

m = re.search(pattern, value)

return m.group(2)

示例:

enter image description here

答案 1 :(得分:0)

这是一个正则表达式,它将在命名组中提取start_dateend_date

如果只有一个日期,则认为它是 start_date

((?<start_date>\d{4}).*?)?(?<end_date>\d{4}|(?<=-)\d{2})?$

Demo