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环境中使用。
热门推荐
商业计划书在融资路演中的作用:为投资者呈现最佳商业理念
职场女性必备:从校园到社会的职场技能提升指南
鱼需要多长时间才能长大到可以吃食物?
意外受傷指甲翻起怎麼辦?專家教您正確處理與注意事項
西藏酥油茶品味高原的温暖与文化
温彬:通胀又升了,如何理解美国经济非典型表现
后交叉韧带损伤怎么诊断
厚植文气,文化惠民空间更聚人气——浙江探索公共文化空间一体化运营模式
生态消费:如何实现可持续生活方式的转变
鄱阳湖蓼子花开候鸟来
“司空见惯”里的“司空”是谁?又见惯了什么?
国际中文教育新实践:科技赋能传统文化 打造沉浸式语言文化课堂
燕窝产品配料清单填写指南及关键成分标注
难治性抑郁症救星?碳酸锂治疗全揭秘!
中国古典舞的呼吸作用及方法
北海 vs 湛江:北部湾两座海滨城市的养老生活全方位对比
感冒声音嘶哑的原因及治疗方法
论持续审计和风险监控在信贷额度管理中的落地
那些华夏祖先绚烂夺目的奇迹发明
和谐号动车座位排列方式及购票座位查找指南
明朝官员工资真相:与唐宋比较及其生活困境
金线莲:中药界的明珠
七杀星的人性格特点及长相、命运特点
什么是战略定位理论?
与疾有关的成语有哪些?揭秘!与疾有关的成语,你了解多少?!
解密气体状态方程:从理想世界到现实应用
统计力学如何解释温度的本质?
2025 年引起轰动的 10 大传感器技术(附全名单)
业委会有权利动用维修基金吗
蒲公英根的功效与作用