Excel VBA,一种模糊匹配
Posted
技术标签:
【中文标题】Excel VBA,一种模糊匹配【英文标题】:Excel VBA, a kind of fuzzy match 【发布时间】:2015-07-15 10:31:14 【问题描述】:我想在 Excel VBA 中自动化一个脚本,但我卡住了。
我有一个字符串 =“患者人数是 x。由此,很多患者是男性。一个特定的男性患者有 3 种致命的疾病。” (字符串会更长)
现在我想做的是搜索“患者”这个词在这个字符串中出现了多少次,即使这些词有拼写问题以及它们是如何写的。
我的想法是让我们以 80% 的置信度来匹配字符串中所有单词的单词“耐心”,我想要的结果是 .. 有 3 个匹配项,其中的单词字符串:“患者”、“患者”、“patint”。 有没有办法做到这一点?
【问题讨论】:
您可以制作一个拼写变体的字典,然后针对字符串中的每个单词将其与潜在匹配数组进行检查。 【参考方案1】:当然是 YMMV,但要注意两件事:
Fuzzy Lookup Add-In for Excel
... 在 Microsoft Excel 中执行文本数据的模糊匹配。它可以 用于识别单个表中的模糊重复行或 模糊连接两个不同表之间的相似行。匹配是 对包括拼写错误在内的各种错误具有鲁棒性, 缩写、同义词和添加/缺失的数据。
计算Levenshtein Distance 也可能有用。
【讨论】:
【参考方案2】:这是 Levenshein 距离的 VBA 实现。您可以根据需要调整阈值。
Public Function Levenshtein(str1 As String, str2 As String) As Integer
On Error GoTo ErrHandler
Dim arrLev, intLen1 As Integer, intLen2 As Integer, i As Integer
Dim j, arrStr1, arrStr2, intMini As Integer
intLen1 = Len(str1)
ReDim arrStr1(intLen1 + 1)
intLen2 = Len(str2)
ReDim arrStr2(intLen2 + 1)
ReDim arrLev(intLen1 + 1, intLen2 + 1)
arrLev(0, 0) = 0
For i = 1 To intLen1
arrLev(i, 0) = i
arrStr1(i) = Mid(str1, i, 1)
Next
For j = 1 To intLen2
arrLev(0, j) = j
arrStr2(j) = Mid(str2, j, 1)
Next
For j = 1 To intLen2
For i = 1 To intLen1
If arrStr1(i) = arrStr2(j) Then
arrLev(i, j) = arrLev(i - 1, j - 1)
Else
intMini = arrLev(i - 1, j) 'deletion
If intMini > arrLev(i, j - 1) Then intMini = arrLev(i, j - 1) 'insertion
If intMini > arrLev(i - 1, j - 1) Then intMini = arrLev(i - 1, j - 1) 'deletion
arrLev(i, j) = intMini + 1
End If
Next
Next
Levenshtein = arrLev(intLen1, intLen2)
Exit Function
ErrHandler:
MsgBox Err.Description
Exit Function
End Function
【讨论】:
感谢大家的回复。我会努力解决的。【参考方案3】:您正在寻找的概念称为“全文搜索”。
我不是 100% 确定,但我认为这不是 Excel 或 VBA 中的原生功能。 据我所知,甚至 MS Access 都不支持这一点。
查看 Alex K 建议的插件或查看在您的应用中嵌入真实数据库。
【讨论】:
【参考方案4】:您可以使用 Soundex2 算法来匹配发音相似的单词。 This SO post 有一些关于 VBA 中 soundex 的指针。 请注意,该算法依赖于主要在英语中发现的特征。
【讨论】:
以上是关于Excel VBA,一种模糊匹配的主要内容,如果未能解决你的问题,请参考以下文章