2017-05-14 121 views
0

我嘗試在OpenRefine 2.6中使用value.match命令將列中的信息呈現分成(至少)2列。然而,這些數據相當混亂。
我有時整整日期:在Openrefine中匹配不同的日期

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 OR 1905-1906

有時一年才

1905

有時一年屬性

August or September 1908

似乎沒有遵循任何特定的模式或順序。沒有其餘屬性

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


我想提取物(至少)CA開始和結束日期的一年,爲了有兩列。

我可以找到使用
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)

+1

在您的例子(你說有時候滿日期結合其他日期和屬性),你可以告訴每行應該是什麼start_date和end_date?目前尚不清楚。 –

+0

非常正確。我會選擇第一個日期作爲start_date和最終日期end_date,或者更好(不知道是否有可能)最早的日期爲start_date,最後的日期爲end_date。 – K3it4r0

回答

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

+0

這很有效:)我會等待看看是否有其他正則表達式的可能性,只是爲了澄清我的想法,但非常感謝你! – K3it4r0

0

這裏是一個正則表達式這將提取在命名組和end_date

如果只有一個日期,那麼它認爲它的START_DATE

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

Demo

+0

已更新,以匹配end_date和2位數,前面加上連字符 –