VBA字符串处理进阶:文本相似度与模糊匹配函数封装
创作时间:
作者:
@小白创作中心
VBA字符串处理进阶:文本相似度与模糊匹配函数封装
引用
360doc个人图书馆
等
12
来源
1.
http://www.360doc.cn/article/67367384_1013795555.html
2.
https://wenku.csdn.net/doc/2yhqvbgbx5
3.
https://blog.csdn.net/oHuaXiaZhiFeng/article/details/8620486
4.
http://www.360doc.cn/article/68414255_925983951.html
5.
http://www.360doc.cn/article/13664199_947520250.html
6.
https://blog.csdn.net/u011785661/article/details/50697529
7.
https://blog.csdn.net/woodcorpse/article/details/116036330
8.
https://blog.csdn.net/ych_ding/article/details/42266603
9.
https://cloud.tencent.com/developer/ask/sof/103025342/answer/111191535
10.
https://www.cnblogs.com/xkdn/p/17850005.html
11.
https://www.exceldemy.com/calculate-levenshtein-distance-in-excel/
12.
https://www.cnblogs.com/apachecn/p/18473566
基于前面的分析和规划,我为您封装了一组进阶的文本处理函数。这些函数包括文本相似度计算、模糊匹配以及必要的预处理功能,旨在帮助您在VBA中更高效地处理字符串数据。
字符串相似度计算
SimilarityRatio 函数
计算两个字符串的相似度比率(0-1范围),基于编辑距离。
Public Function SimilarityRatio(ByVal str1 As String, ByVal str2 As String) As Double
Dim maxLen As Long
str1 = CleanString(str1)
str2 = CleanString(str2)
If str1 = str2 Then
SimilarityRatio = 1
Exit Function
End If
maxLen = WorksheetFunction.Max(Len(str1), Len(str2))
SimilarityRatio = 1 - (LevenshteinDistance(str1, str2) / maxLen)
End Function
LevenshteinDistance 函数
计算两个字符串的编辑距离,使用动态规划实现。
Public Function LevenshteinDistance(ByVal s As String, ByVal t As String) As Long
Dim d() As Long, i As Long, j As Long, cost As Long
Dim m As Long, n As Long
m = Len(s)
n = Len(t)
ReDim d(0 To m, 0 To n)
For i = 0 To m: d(i, 0) = i: Next
For j = 0 To n: d(0, j) = j: Next
For i = 1 To m
For j = 1 To n
cost = Abs(StrComp(Mid(s, i, 1), Mid(t, j, 1), vbTextCompare))
d(i, j) = WorksheetFunction.Min( _
d(i - 1, j) + 1, _
d(i, j - 1) + 1, _
d(i - 1, j - 1) + cost)
Next
Next
LevenshteinDistance = d(m, n)
End Function
JaccardSimilarity 函数
基于词集计算两个字符串的Jaccard相似度。
Public Function JaccardSimilarity(ByVal strA As String, ByVal strB As String) As Double
Dim wordsA As Variant, wordsB As Variant
Dim union As Collection, intersect As Collection
Set union = New Collection
Set intersect = New Collection
wordsA = Split(RemoveNonAlphanumeric(strA), " ")
wordsB = Split(RemoveNonAlphanumeric(strB), " ")
'计算并集和交集
BuildUnionAndIntersect wordsA, wordsB, union, intersect
If union.Count = 0 Then
JaccardSimilarity = 0
Else
JaccardSimilarity = intersect.Count / union.Count
End If
End Function
模糊匹配
FuzzyMatch 函数
在Excel单元格区域中查找与目标字符串相似的项,返回匹配单元格地址及相似度。
Public Function FuzzyMatch(ByVal searchStr As String, ByVal rangeToSearch As Range, Optional threshold As Double = 0.7) As Variant
Dim result() As Variant, cell As Range, cnt As Long
ReDim result(1 To rangeToSearch.Count, 1 To 2)
searchStr = CleanString(searchStr)
For Each cell In rangeToSearch
If SimilarityRatio(searchStr, CleanString(cell.Value)) >= threshold Then
cnt = cnt + 1
result(cnt, 1) = cell.Address
result(cnt, 2) = Format(SimilarityRatio(searchStr, cell.Value), "0.00%")
End If
Next
ReDim Preserve result(1 To cnt, 1 To 2)
FuzzyMatch = result
End Function
辅助函数
CleanString 函数
清洗字符串,去除特殊字符,统一转换为小写。
Public Function CleanString(ByVal str As String) As String
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
With regex
.Global = True
.IgnoreCase = True
.Pattern = "[^a-zA-Z0-9\s]"
CleanString = .Replace(str, "")
End With
CleanString = LCase(CleanString)
End Function
RemoveNonAlphanumeric 函数
去除字符串中的非字母数字字符。
Public Function RemoveNonAlphanumeric(ByVal str As String) As String
Dim regex As Object
Set regex = CreateObject("VBScript.RegExp")
With regex
.Global = True
.IgnoreCase = True
.Pattern = "[^a-zA-Z0-9]"
RemoveNonAlphanumeric = .Replace(str, "")
End With
End Function
BuildUnionAndIntersect 子程序
构建两个词集的并集和交集。
Private Sub BuildUnionAndIntersect(ByRef arr1, ByRef arr2, ByRef unionColl As Collection, ByRef intersectColl As Collection)
Dim dict As Object, elem As Variant
Set dict = CreateObject("Scripting.Dictionary")
'处理第一个数组
For Each elem In arr1
elem = LCase(Trim(elem))
If Len(elem) > 0 Then
dict(elem) = 1
AddToCollection unionColl, elem
End If
Next
'处理第二个数组
For Each elem In arr2
elem = LCase(Trim(elem))
If Len(elem) > 0 Then
If dict.exists(elem) Then
If dict(elem) = 1 Then
AddToCollection intersectColl, elem
dict(elem) = 2
End If
Else
AddToCollection unionColl, elem
End If
End If
Next
End Sub
AddToCollection 子程序
向集合中添加元素,避免重复。
Private Sub AddToCollection(ByRef coll As Collection, ByVal item As String)
On Error Resume Next
coll.Add item, item
On Error GoTo 0
End Sub
使用示例
Sub Demo()
'相似度计算
Debug.Print SimilarityRatio("apple", "apples") '→ 0.8
'模糊匹配查找
Dim matches As Variant
matches = FuzzyMatch("Excel", Range("A1:A10"), 0.6)
'Jaccard相似度
Debug.Print JaccardSimilarity("Hello world", "World hello") '→ 1.0
End Sub
特点说明
性能优化:Levenshtein距离使用动态规划算法,处理20字符以内的字符串效率较高。
预处理集成:内置CleanString函数进行统一预处理,确保比较前字符串的一致性。
扩展性设计:模糊匹配函数可直接应用于Excel单元格区域,方便在实际工作中使用。
阈值控制:所有相似度计算均可设置灵敏度阈值,用户可以根据需要调整匹配的严格程度。
兼容处理:统一使用vbTextCompare进行不区分大小写的比较,确保结果的准确性。
注意事项
- 需确保已实现引用的基础函数(如CleanString、RemoveNonAlphanumeric等),这些函数用于字符串的预处理。
- 可以根据实际需求添加更多的错误处理逻辑,以增强代码的健壮性。
- 对于处理大量数据的场景,建议结合数组处理进一步优化性能。
通过这组函数,您可以在VBA中实现更高级的文本处理功能,特别是在需要进行模糊匹配和相似度计算的场景下。这些函数不仅能够提高数据处理的效率,还能确保结果的准确性,非常适合在Excel环境中使用。
热门推荐
赵本山春晚经典回顾:从草根到小品之王
威海自驾游摄影攻略:10个绝美打卡点详解
威海千里山海自驾游:最美海滨风光打卡地
倾听与尊重:建立良好亲子关系的关键
原油2005合约交割日回顾:市场风云再起?
交割日效应:股市大跌真相揭秘
KPL职业选手教你如何选择发育路英雄
王者荣耀:公孙离上分攻略
《王者荣耀》发育路高手速成秘籍!
S34赛季发育路T0梯队评测:敖隐与戈娅谁更强?
阿离:发育路最强射手?从技能到实战全面解析
王者荣耀亚瑟最强出装指南
第二类椭圆积分:物理学计算的革新工具
椭圆积分:高数界的神秘大咖!
老奶奶也能成网红?揭秘老年网红爆火背后的故事
春运:“流动”彰显中国活力
春节带娃打卡西安古城墙,感受千年历史
春节带娃游丽江:五天四晚亲子游完全攻略
带着孩子玩转故宫:亲子游完全攻略
中国电影出海正当时:从戛纳到全球,中国电影如何讲好中国故事?
秋冬季节如何预防青少年抑郁症?
一颗番茄的发迹史
缓解女性更年期的养生食谱
自制黑芝麻豆浆,15分钟搞定!
黑芝麻豆浆:一杯豆浆,从头到脚的全方位滋养
如何检查CPU和主板的具体型号是否匹配?
10个关于李小龙的鲜为人知的事实,你可能从未听说!
留学生必读:听说读写全方位提升攻略
王者荣耀:夏侯惇教你如何在游戏中克制典韦
《恐怖奶奶》最新版来袭!你敢挑战五天逃脱极限吗?