模式 ( regex ) 和找到的值之间的相似性

Posted

技术标签:

【中文标题】模式 ( regex ) 和找到的值之间的相似性【英文标题】:similarity between pattern ( regex ) and the value found 【发布时间】:2014-07-01 08:07:16 【问题描述】:

我有一张包含文字信息的图片,并且:

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

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

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

图片中的值是

12/02/2014

但是提取了 OCR:

12? /02 -2014

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

【问题讨论】:

这实际上取决于您的 OCR 软件的准确性和您正在扫描的材料的质量。可能存在各种错误 - 添加的问号(不确定匹配,由 OCR 标记)、不匹配的字符 - 例如l 或 I 代替 1,O 或 o 代替 0 等。我建议您允许对 OCR 材料进行一些预处理,然后尝试使用正则表达式进行解析。 是的,这取决于它,但我没有选择我必须考虑与模式非常相似的值,即使它不匹配 您是否允许您的客户在使用正则表达式模块处理之前编辑 OCR 模块识别的文本? 还有,大相似度代表什么具体的东西。 据我了解,OP 询问是否有办法处理来自 OCR 软件的错误/不确定匹配,并使用一些正则表达式来识别捕获的数据可能是:float、date、号码等... 【参考方案1】:

如果没有允许这种歧义的修改,则不能使用特定的正则表达式来匹配具有歧义的模式。例如,如果您希望允许在要匹配的字符串的任意位置插入额外字符,则正则表达式模式需要提供这些任意字符。这使得模式很快变得丑陋:例如,匹配int 的模式非常简单,

\\d+

允许在两者之间使用非数字的相同模式如下所示:

(\\d\\D*)+

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

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

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

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

var cost = (s[i] == t[j]) ? 0 : 1;

改成

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

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

您可以通过检查 Levenshtein 距离来决定比赛的质量。距离为零表示完美匹配;一到两个距离对于短模式来说非常好;五个或更多的距离可能是不可接受的。

【讨论】:

我开始寻找某种用于数字的 soundex 算法,但您建议的方法似乎是一种更好的方法。一个问题 - Levenshtein 距离算法是否可以用于“噪声字符” - 例如额外的空格、问号、一个被 OCR 识别为两个字符的符号等等? @ZlatinZlatev 是的,您也可以通过更改成本函数来做到这一点。例如,当输入具有常规字符时,您可以通过为cost 分配更大(例如,5)值来惩罚与“噪声”字符不匹配的成本低于与“真实”字符不匹配的成本,并且1 与“噪声字符”不匹配。 您使用的示例(int cost)仅适用于pattern int或short pattern? @manu 我不会使用模式来区分 intshort - 这是可行的,但它太复杂了。我会识别一个没有符号或小数点的数字(实际上,这就是模式所代表的),然后尝试查看它是否适合一个字节,然后是一个短的,一个 int 或一个长的。跨度> 不能举个例子吗?

以上是关于模式 ( regex ) 和找到的值之间的相似性的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 中用 RegEx 替换列中的值

如何使用 RegEx 提取键之间的值?

雪花 - 在两个数组之间返回不同(不相似)的值

通过在两个 Pandas 数据帧之间迭代来识别相似的值。

REGEX 匹配整数 6 到 10

PYSPARK:如何在 pyspark 数据框中找到两列的余弦相似度?