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环境中使用。
热门推荐
拥有成人高考学历能否报考公务员考试?
为什么云手是所有门派太极拳的母式?原来是这样……
RS-485总线电平异常解决方案解析
跑者须知:什么是“等渗”“高渗”“低渗”饮料
盐吃多了会伤肾吗
2025-2033年全球六甲基二硅氮烷(HMDS)市场研究报告
生活方式调整能治疗Barrett?一文了解生活干预全指南
南京一日游最佳路线推荐
转融券业务明起暂停:将如何影响市场?哪些股票转融券余额较高?
港股窝轮投资必读:收费标准详解及其对投资策略的影响
豆汁怎么做的?制作豆汁的详细步骤指南
惠珍这个名字的含义与寓意分析
广西螺蛳粉:舌尖上的美食传奇
一碗正宗螺蛳粉:从食材到工艺的匠心传承
属羊和属牛相克怎么破解?
深入解析激光发生器的原理与应用
菌种是什么?有什么主要的作用
传奇游戏版本更新的必要性及其影响
五险一金是否包括个人所得税的计算与缴纳问题
濒死感是什么感觉?如何区分正常与异常的心理状态?
ERP实施助理的工作职责与技能要求详解
老年人老打嗝是什么病的前兆
蓝绿色婚礼布置:简约与自然的浪漫交融
科尔沁草原:草原的辽阔与自由
起拍价19.7亿元,郑州最大商业综合体断臂求生
长期服用二甲双胍的注意事项
柠檬醛有什么作用?应用在哪些方面?
个人养老金的概念是什么?
Excel表格中单元格内容上下居中显示的多种方法
盗汗发冷头晕,这些症状真的是艾滋病的预兆吗?