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环境中使用。
热门推荐
深度科普!蛀牙断了牙根还在肉里怎么办?需要拔掉吗?不拔牙根可以直接镶牙吗?
人际交往怎样保护自己
蛀牙:不容小觑的口腔隐患
总和孩子聊不来?父母需要先迈出这一步!
Word与Excel如何关联
合谷穴:虎口处的神奇穴位
自查简历只需要这六步
怎么将数据导入Excel分类
重庆旅游必去之地:洪崖洞——巴渝风情与现代光影的完美交融
王鹤棣:从《苍兰诀》爆火到演技争议,一位年轻演员的转型之路
暨大产学研探秘:护肤品黑科技揭秘
王鹤棣2025:从古偶到实力派的关键转型
王鹤棣新剧《以爱为营》爆红?网友热议:从扑街到逆袭!
王鹤棣:从《苍兰诀》到顶流,公益之路五年行
烧脑问题|焙烧、煅烧、烧结、灼烧有何区别?
流动化学和微反应技术特点
人工智能AI如何提升工业生产效率
用智能手机高效管理会展工作
中国展览馆协会启动第十期展馆运营管理培训,助力行业人才升级
了解更年期焦虑症——症状和解决方案
职场压力大?这招教你轻松应对!
高压职场生存指南:应对刻薄领导,实现职业突破
保研博主重启运营攻略:如何避免老粉取关?
济宁市一院专家教你应对输尿管肿瘤化疗心理挑战
中医食疗新潮流:防治腰突
Jelmyto:输尿管肿瘤化疗的新希望
冬季如何有效预防腰椎间盘突出?
3万人小区创业指南:从0到1的实战攻略
3万人小区创业实战攻略:从项目选择到推广落地
宝鸡文旅新动向:九成宫与关山草原的新篇章