如何获得正则表达式的最近匹配项

时间:2015-12-04 10:01:32

标签: python regex

我有一个代码,用于使用正则表达式从文本中提取日期(格式= 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',则会失败。如何为这样的场景编写代码,它也会选择最接近的匹配。

3 个答案:

答案 0 :(得分:2)

有几种方法可以实现与正则表达式的近似匹配。最“理论上直截了当”的方法很可能要求您对正则表达式edit-distance执行dynamic programming - DFA计算。

这是一个相当棘手的代码算法,它没有太多的实现。最着名的是Agrep(从技术上讲,agrep工具实现了几种算法,但最常见的是模糊正则表达式匹配)。

使用此关键字进行简短的Google搜索会显示this library,它似乎具有Python绑定,可能正是您所需要的。

答案 1 :(得分: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']

然后尝试将所有O替换为0

>>>[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

N.B。你不会得到100%准确的结果,因为你的数据是灾难,而是使用像Abbyy那样可以提高准确性的良好ocr引擎。

修改

如果您想实现某种fuzzymatch / Levenshtein Distance,请使用FuzzyWuzzy模块。

答案 2 :(得分: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'