在 Openrefine 中匹配不同的日期
Matching diverse dates in 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-05
或 1905-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。
此外,我很乐意了解如何提取其他信息的一些线索,例如
如果文本中存在 published 或 printed 或 executed -> 将日期复制到新的列名“执行”。
应该类似于创建一个新列
if(value.match("string1|string2|string3" + (\d{4}), "perform the operation", do nothing)
value.match()
是一个非常有用但有时很棘手的函数。要从文本中提取模式,我更喜欢使用 Python/Jython 的正则表达式:
import re
pattern = re.compile(r"\d{4}")
return pattern.findall(value)
从那里,您可以创建一个将所有年份串联起来的字符串:
return ",".join(pattern.findall(value))
或select只有第一个:
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)
示例:
这是一个正则表达式,它将提取命名组中的 start_date
和 end_date
:
如果只有一个日期,则认为是 start_date :
((?<start_date>\d{4}).*?)?(?<end_date>\d{4}|(?<=-)\d{2})?$
我正在尝试使用 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-05
或 1905-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。
此外,我很乐意了解如何提取其他信息的一些线索,例如
如果文本中存在 published 或 printed 或 executed -> 将日期复制到新的列名“执行”。
应该类似于创建一个新列
if(value.match("string1|string2|string3" + (\d{4}), "perform the operation", do nothing)
value.match()
是一个非常有用但有时很棘手的函数。要从文本中提取模式,我更喜欢使用 Python/Jython 的正则表达式:
import re
pattern = re.compile(r"\d{4}")
return pattern.findall(value)
从那里,您可以创建一个将所有年份串联起来的字符串:
return ",".join(pattern.findall(value))
或select只有第一个:
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)
示例:
这是一个正则表达式,它将提取命名组中的 start_date
和 end_date
:
如果只有一个日期,则认为是 start_date :
((?<start_date>\d{4}).*?)?(?<end_date>\d{4}|(?<=-)\d{2})?$