模式(正则表达式)与找到的值之间的相似性

mar*_*ine 5 java regex ocr error-correction

我有一个包含文本信息的图像,并且:

  1. 我从中提取/裁剪一个小图像
  2. 我正在使用OCR从小图像中提取文本
  3. 检查提取的值是否与模式(浮点数,日期...)匹配(如果是)
  4. 我将值存储在数据库中

问题是:有时ocr提取一个带有一些符号的值,因此它与模式示例不匹配:对于模式日期,我有:

pattern = "(0[1-9]|[12][0-9]|3[01])/(0[1-9]|1[012])/(19|20)\d\d"
Run Code Online (Sandbox Code Playgroud)

图像的值是

12/02/2014
Run Code Online (Sandbox Code Playgroud)

但是OCR提取了:

12? /02 -2014
Run Code Online (Sandbox Code Playgroud)

我希望得到模式和提取的值之间的相似性(最近对待它)有没有办法在不改变模式的情况下做到这一点?

das*_*ght 3

如果不进行允许此类歧义的修改,则特定的正则表达式不能用于匹配具有歧义的模式。例如,如果您希望允许在匹配的字符串的任意位置插入额外的字符,则正则表达式模式将需要对这些任意字符进行规定。这使得模式很快变得丑陋:例如,虽然匹配 an 的模式int非常简单,

\\d+
Run Code Online (Sandbox Code Playgroud)

允许中间有非数字的相同模式如下所示:

(\\d\\D*)+
Run Code Online (Sandbox Code Playgroud)

随着图案变大,这会变得越来越难看,所以这种方法不是很好。

我建议用实现Levenshtein distance变体的算法替换基于模式的匹配。

原始的 Levenshtein 距离算法采用两个字符串,并返回需要对一个字符串进行修改才能获得另一个字符串的次数。您的算法应该采用一个字符串和一个模式。该模式应该使用某种数字指示符(例如,#)并将所有其他字符“按字面意思”视为字符串字符。您可以修改算法中使用的指示符函数,以便在发送 a#任何数字时返回零,1否则返回零。

看一下两行矩阵的实现,它是最节省空间的。指标函数在这一行实现:

var cost = (s[i] == t[j]) ? 0 : 1;
Run Code Online (Sandbox Code Playgroud)

将其更改为

int cost = (s[i] == t[j] || (Character.isDigit(s[i]) && t[j] == '#')) ? 0 : 1;
Run Code Online (Sandbox Code Playgroud)

将允许您“匹配”数字。您的代码还可以在进行匹配之前删除字符串中的所有空格。

您可以通过检查编辑距离来决定比赛的质量。距离为零表示完美匹配;对于短图案来说,一到两个距离就相当不错了;五个或更多的距离可能是不可接受的。