如何确定最接近正则表达式模式的匹配

可以说我有以下列表:

abc_Pickled_efg
abc_Pickller_efg
abcd_something_Picklesefgh
efg_Pickles_abc

和正则表达式模式:

abc.*Pickles.*efg

列表中的所有这些都不匹配该模式。但是,我将如何查找最接近的匹配项(在本例中为abc_Pickled_efg)。是否有一些python模块或某些可以说是92%匹配还是0%匹配的东西的东西?

我的想法是我可以遍历模式并查看每个符号是否匹配,即:

a  => a = 1 point
b  => b = 1 point
c  => c = 1 point
.* => _ = 1 point
P  => P = 1 point
i  => i = 1 point
c  => c = 1 point
k  => k = 1 point
l  => l = 1 point
e  => e = 1 point
r  => d = 0 point
.* => _ = 1 point
e  => e = 1 point
f  => f = 1 point
g  => g = 1 point
-----------------
         14 points out of 15 possible ~= 93% match

这有意义吗?或者是否有类似的事情?

moon_zero 回答:如何确定最接近正则表达式模式的匹配

如何在正则表达式中完成?

您可以使用具有内置模糊匹配技术的PyPi regex模块。这种模糊技术可让您根据正则表达式错误,允许的数目以及每种模糊匹配错误的得分来指定字符串中允许和不允许发生的事情。可以在here中找到此信息。

就正则表达式而言,您将使用以下内容(很明显,如果您在问题中指定的正则表达式是预先确定的,则可以将其串联起来;在(?:之前加上){e}): / p>

(?:abc.*Pickles.*efg){e}

在上述正则表达式中,{e}允许在匹配字符串时出现任何类型的错误(删除,插入,替换)。您可以根据自己的喜好对其进行修改,下面列出了一些示例(许多示例是从我在第一段中提供的链接中复制的):

  • {d}仅删除
  • {d,i}仅删除和插入
  • {d,s,i}的删除,替换或插入(与{e}相同)-顺序无关紧要
  • {e<=3}最多允许3个错误
  • {i<3}允许插入少于3次
  • {1<=e<3}允许至少1个错误,但少于3个错误
  • {1<=2,d>2}最多允许2次插入,至少2次删除
  • {2i+d2+1s<=4}每个插入成本2,每个删除成本2,每个替换成本1,总成本不得超过4
  • {i<=1,d<=1,s<=1,2i+2d+1s<=4}最多插入1个,最多删除1个,最多替换1个;每个插入成本2,每个删除成本2,每个替换成本1,总成本不得超过4

其实现是什么样的?

现在您已经了解了这是什么以及它如何工作,我们可以继续进行实际的实现。以下代码在计算中使用了正则表达式模块的fuzzy_counts,以根据其得分确定最佳字符串。我的计算将转换为百分比并按以下方式工作(您可以根据自己的喜好进行更改,并结合以上信息,更改正则表达式遇到的每种错误的得分):

# 100 * (1 - (fuzziness/length of original string))
100*(1 - (n/len(s)))

See this code working here

注意:我使用pprint很好地显示了输出;不必要使用它,只是使结果更易于阅读。

import regex,pprint

strings = [
    "abc_Pickled_efg","abc_Pickller_efg","abcd_something_Picklesefgh","efg_Pickles_abc"
]

r = r'(?:abc.*Pickles.*efg){e}'
matches = []

for i,s in enumerate(strings):
    x = regex.fullmatch(r,regex.BESTMATCH)   # match result
    n = sum(x.fuzzy_counts)             # fuzziness
    c = 100*(1 - (n/len(s)))            # closeness
    matches.append(c)

result = sorted(zip(strings,matches),key=lambda x: x[1],reverse=True)

pp = pprint.PrettyPrinter(indent=4)
pp.pprint(result)

结果:

[   ('abcd_something_Picklesefgh',96.15384615384616),('abc_Pickled_efg',93.33333333333333),('abc_Pickller_efg',87.5),('efg_Pickles_abc',60.0)]
本文链接:https://www.f2er.com/3148971.html

大家都在问