例如,我想匹配字词“New York”前面的一个2位数字。困难来自于文本是从PDF的OCR,所以我想做一个模糊匹配。我想匹配:
12 New York 24 Hew York 33 New Yobk
和其他“关闭”匹配(在Levenshtein距离的意义上),但不是:
aa New York 11 Detroit
显然,我需要指定匹配的允许距离(“模糊性”)。
根据我的理解,我不能使用String :: Approx Perl模块来做到这一点,因为我需要在我的匹配中包含一个正则表达式(匹配前面的数字)。
此外,我应该注意,这是一个非常简化的例子,我真的想匹配,所以我不是在寻找一个暴力方法。
已编辑以添加:
好吧,我的第一个例子太简单了。我不是想让人们挂在前面的数字 – 对不起的例子。这里有一个更好的例子。考虑这个字符串:
指派者,通过MESHS ASSIGN1IBNTS,ALUSCHALME& S MANOTAC / RURINGCOMPANY,A COBPOBAT1OH DELTA / ABE。
这其实是说:
指派者,按照MESNE分配,ALLIS-CHALMERS制造公司,DELAWARE公司
我需要做的是提取短语“ALUSCHALME& S MANOTAC / rURINGCOMPANY”和“DELAY / ABE”。 (我意识到这可能看起来像疯狂,但我是一个乐观主义者。)一般来说,模式将看起来像这样:
/ Assignor(,通过mesne赋值)?到(公司名称),(州)的公司/ i
其中匹配是模糊的。
你的第二个描述实际上在这里是有帮助的,因为模式和文本应该相当长。 q-gram距离不能像“York”这样的单词很好地工作,但是如果你的典型模式是一个完整的地址,那应该很好。
尝试这样:
>将你的文本和模式转换为缩小的字符集,如大写字母,剥离,文字(单词之间的一个空格)所有符号替换为“#”或某事。
>选择q-gram长度,以使用。尝试3或2.我们称之为q = 3。
>建立每个文本的qgram-profile:
>将每个文本拆分为q字,即。 NEW_YORK变为[NEW,EW_,W_Y,_YO,ORK],将其与每个文本一起保存。
>如果你搜索你的模式,然后,你做同样的模式,
>循环通过你的text-qgram数据库和
>计数每个模式/文本对有多少qgram是相同的。
>每个命中将提高分数1。
>具有最高分数的文本是您最好的点击。
如果你这样做,你可以调整这个算法:
>添加所有的文本(以及搜索之前的模式),与q-1特殊字符,所以即使你的短语将得到一个体面的配置文件。例如纽约成为^^纽约$$。
>你甚至可以用“x”替换所有辅音,用“o”替代元音,等等。以这种方式玩几个字符类,或者甚至通过替换一组字符来创建超级符号,即CK变成K,或SCH变成$。
>当通过qgram命中提高分数时,您可以通过其他事情调整值1,如文本的长度差异vs模式。
>存储2克和3克两者,并且当计数时,然后不同地称重。
注意,在这里描述的基本形式的该算法在搜索期间不具有良好的运行时间,即O(| T | * | P |)(其中| T |和| P |是文本和模式的总长度)。这是因为我描述你循环所有的文本,然后在你的模式。因此,这只适用于中等大小的文本库。如果你花了一些思想,你可以创建一个高级索引结构在q克(可能使用哈希表),所以这可能是实用的巨大的文本基地以及。