2015-12-04 87 views
1

我有一個代碼使用正則表達式從文本(format = mm-dd-yyyy)中提取日期。如何獲得最接近的匹配正則表達式

注意:該文本是使用OCR在票據圖像上獲得的。所以,預期的日期格式是mm-dd-yyyy,但它可以是使用OCR獲取的任何隨機文本。

import re 
date_reg_exp = re.compile('\d{2}[-/.]\d{2}[-/.]\d{4}') #works for mm-dd-yyyy 
matches_list=date_reg_exp.findall(test_str) 
for match in matches_list2: 
    print match 

如果我有一個字符串'This is a text extracted from OCR 09-11-2015'上面的代碼工作和結果的日期作爲輸出'09-11-2015'。但是,如果我有一個字符串'This is o text extractud fram OCR 09-11-201 5''This is o text xtractud fram OCR 09-11-201''This is o text xtractud fram OCR O9-11-201'它會失敗。我如何爲這樣的場景編寫代碼,在這個場景中它也挑選最接近的匹配項。

+1

它取決於「最近」的定義。你的例子可以通過在匹配之前刪除空格來處理。 – eph

+0

好的。讓我更具體一些。如果我有一個字符串''字符串是09-11-201',這是正則表達式最接近的匹配。這應該被打印爲輸出。 輸出 - '09-11-201' –

+0

所有的月份和日期都是正確的格式,只是年份已經搞亂了嗎? –

回答

0

試戴

O?\d{1,2}[-/\.]\d{2}[-/\.][\d\s]{2,} 

由於如下─

>>>import re 
>>>s = """If I have a string 'This is a text extracted from OCR 09-11-2015' the above code works and results the Date as output '09-11-2015'. But, if I have a string 'This is o text extractud fram OCR 09-11-201 5' or 'This is o text xtractud fram OCR 09-11-201' or 'This is o text xtractud fram OCR O9-11-201' it fails. How to I write a code for such scenario where it also picks up the nearest match.""" 
>>>re.findall(r'O?\d{1,2}[-/\.]\d{2}[-/\.][\d\s]{2,}',s) 
>>>['09-11-2015', '09-11-2015', '09-11-201 5', '09-11-201', 'O9-11-201'] 

然後嘗試所有O0取代。

>>>[i.replace('O','0') for i in ['09-11-2015', '09-11-2015', '09-11-201 5', '09-11-201', 'O9-11-201']] 
>>>['09-11-2015', '09-11-2015', '09-11-201 5', '09-11-201', '09-11-201'] 

查看即時DEMO

或 - 如果日期分隔符在日期如/,.,-然後下面應提取日期 - 它認爲所有l33t字符。像$5

\b[\w\$\s]{2}\s*[\.-/-]\s*[\w\$]{2,}\s*[\.-/-]\s*[\w\$]{2,} 

查看即時DEMO

注:你不會得到100%準確的結果,因爲你的數據是一場災難,而是使用好的ocr引擎,如Abbyy,這可以提高準確性。


編輯

如果你想實現某種fuzzymatch的/ Levenshtein Distance然後使用FuzzyWuzzy模塊。

+0

這適用於額外的空間。但是如果缺少像'09 -11-201'這樣的數字,它就會失敗。我需要一個通用的'正則表達式'或某種算法來幫助挑選這樣的場景。 –

+0

你可以發佈所有可能的日期格式,而我可以使正則表達式一般化。 – SIslam

+0

現在我只有一種格式的日期'mm-dd-yyyy'。我實際上正在從事OCR(從賬單提取日期)。所以我需要這個場景。聽說Levenshtein,但我並沒有意識到它在這種情況下的實現,因爲「日期」不是英文單詞。 –

0

這不是標題要求 但是如您所說的Levenshtein距離可能對您的情況有用。

from dateutil.parser import parse 

s = 'This is o text xtractud fram OCR O9-11-201' 

parse(s, fuzzy=True) 

datetime.datetime(201, 9, 11, 0, 0) 

Dateutil提供了一個模糊的日期時間分析器。

這適用於'09-11-201'但不會對'09-11-201 5'

+0

它會適用於「O9-11-2015」或「09 -11-201S」嗎?因爲OCR引擎可能會對'0'和'O'以及'5'和'S'產生混淆。 –

+0

在上面的例子中,我錯誤地使用了'O'而不是'0'。它在這裏工作,因爲字母表不在日期之間,而是簡單地停止。 因此,它不適用於字母表。如果您無法找到您應該找到的日期,則可以在更換所有S和O後編寫更多代碼來提取日期。 – Shivendra

2

工作有幾種方法你可以實現正則表達式的近似匹配。最「理論上直接」的方法很可能會要求您對DFA執行edit-distance類似dynamic programming的計算。

這是一個相當棘手的編碼算法,它沒有太多的實現。最有名的是Agrep(從技術上說,agrep工具實現了幾種算法,但其中最爲人熟知的是模糊正則表達式匹配)。

通過此關鍵字使用Google搜索簡短的this library,它似乎有Python綁定,可能正是你需要的。

+0

如果您對圖書館很熟悉,請通過提供示例幫助我理解。 –

+0

已經在那裏給出的例子有什麼問題? https://github.com/laurikari/tre/blob/master/python/example.py –

相關問題