前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >字符处理——大小写转换编程思路扩展

字符处理——大小写转换编程思路扩展

作者头像
xyj
发布2020-07-28 11:54:00
6700
发布2020-07-28 11:54:00
举报
文章被收录于专栏:VBA 学习VBA 学习

1、简单实现

前面我们实现了首字母大写、转换大写、转换小写3个功能,如果再实现一个大小写互换,有了前面的基础,实现起来应该没什么大问题:

代码语言:javascript
复制
Function FUpperLowerSwap(str As String) As String
    Dim i As Long
    Dim tmp As String
    
    For i = 1 To VBA.Len(str)
        tmp = VBA.Mid$(str, i, 1)
        
        If tmp >= "a" And tmp <= "z" Then
            tmp = VBA.UCase$(tmp)
            Mid(str, i, 1) = tmp
        ElseIf tmp >= "A" And tmp <= "Z" Then
            tmp = VBA.LCase$(tmp)
            Mid(str, i, 1) = tmp
        End If
    Next
    
    FUpperLowerSwap = str
End Function

注意这里的Mid(str, i, 1) = tmp,里面的Mid是一个语句,不是字符串处理函数。功能是替换str中的字符。

实现了FUpperLowerSwap函数,我们只要调用这个函数就可以实现字符串中的字母大小写互换了。

2、思路扩展

函数里面主要是通过判断字符是否是小写字符或者是否是大写字符,然后进行转换,在这里这个功能比较简单,只需要两个If判断就可以。如果是要实现一个更复杂的功能,需要判断的东西更多,那么只能不停的增加If判断。

这样不但代码看起来混乱、复杂,而且一旦要处理的数据量太多,程序效率也会很低。

这里我们介绍一种比较常用的编程思路,使用数组来减少If的使用。

通过前面的了解,我们知道字母都是ASCII编码的,数字不会超过255,所以,我们首先可以使用一个下标是0-255的数组,分别对应ASCII编码的字符,那么字母自然也能够和数组一一对应。

数组记录什么呢?

我们这里是希望能够实现字母的大小写转换,所以需要记录的就是字符要进行转换的时候,需要去做什么。

根据前面提到过的大小写字母相差编码固定的知识,我们使用数组记录的就是这个需要增加的数字(减少的时候就是负数)。

而为了功能的更加完整,我们记录一个字符转换为大写、转换为小写、大小写转换3个数据,这个时候使用自定义的结构体就非常合适了:

代码语言:javascript
复制
Private Type Letter
    '转换为大写需要增加的数字,可以是负数
    ToUpper As Integer
    '转换为小写需要增加的数字,可以是负数
    ToLower As Integer
    '转换需要增加的数字,可以是负数
    Change As Integer
End Type

然后是要初始化:

代码语言:javascript
复制
Private Function InitLetters() As Letter()
    Dim ret() As Letter
    'ASCII字符不会超过255
    ReDim ret(&HFF) As Letter
    
    Dim i As Long
    '记录小写字母需要转换的时候,应该增加的数字
    For i = VBA.Asc("a") To VBA.Asc("z")
        ret(i).ToUpper = VBA.Asc("A") - VBA.Asc("a")
        ret(i).Change = ret(i).ToUpper
    Next
    
     '记录大写字母需要转换的时候,应该增加的数字
    For i = VBA.Asc("A") To VBA.Asc("Z")
        ret(i).ToLower = VBA.Asc("a") - VBA.Asc("A")
        ret(i).Change = ret(i).ToLower
    Next
    
    '其他的字符都不需要初始化,默认为0即可
    
    InitLetters = ret
End Function

在这个基础上,来实现FUpperLowerSwap函数,因为转换方式有3种,这里再使用枚举来定义:

代码语言:javascript
复制
Private Enum EChange
    Upper
    Lower
    Change
End Enum

函数实现:

代码语言:javascript
复制
Private Function ToUpperLowerOrChange(str As String, ls() As Letter, C As EChange) As String
    Dim i As Long
    Dim b() As Byte
    'String转换为byte来处理
    b = str
    
    'VBA使用的是Unicode编码,每个字符占用2个字节
    For i = 0 To UBound(b) - 1 Step 2
        '字符低位在前面,高位在后面,所以如果是ASCII字符的话,高位就是0
        If b(i + 1) = 0 Then
            '这里不需要再判断是否是字母来,因为未初始化的ASCII字符转换的时候都是增加0,不会影响
            Select Case C
                Case EChange.Upper
                b(i) = b(i) + ls(b(i)).ToUpper
                
                Case EChange.Lower
                b(i) = b(i) + ls(b(i)).ToLower
                
                Case EChange.Change
                b(i) = b(i) + ls(b(i)).Change
            End Select
        End If
    Next
    
    ToUpperLowerOrChange = b
End Function

主函数再调用:

代码语言:javascript
复制
Sub UpperLowerSwap()
    Dim rng As Range, selectRng As Range
    Dim ls() As Letter
    
    '确保选中的是单元格
    If TypeName(Selection) = "Range" Then
        Set selectRng = Selection
        
        ls = InitLetters()
        For Each rng In selectRng
            rng.Value = ToUpperLowerOrChange(VBA.CStr(rng.Value), ls, EChange.Change)
        Next rng
    End If
    
    Set rng = Nothing
    Set selectRng = Nothing
End Sub

3、性能测试

代码语言:javascript
复制
Sub testletter()
    Dim strs(500000) As String
    Dim ls() As Letter
    Dim t As Double
    
    Dim i As Long
    For i = 0 To UBound(strs)
        strs(i) = "abABalsdfasSLDFJGOAEIsl中文..asdf1.,..,msfi"
    Next
    
    t = VBA.Timer
    Debug.Print "扩展方法:"
    Debug.Print "开始时间:", t
    
    ls = InitLetters()
    
    For i = 0 To UBound(strs)
        ToUpperLowerOrChange strs(i), ls, Change
    Next
    Debug.Print "结束时间:", VBA.Timer
    Debug.Print "使用时间:", VBA.Timer - t
    
    Debug.Print "————————————————————————————"
    
    
    t = VBA.Timer
    
    Debug.Print "普通方法:"
    Debug.Print "开始时间:", t
    For i = 0 To UBound(strs)
        FUpperLowerSwap strs(i)
    Next
    Debug.Print "结束时间:", VBA.Timer
    Debug.Print "使用时间:", VBA.Timer - t
End Sub

本人电脑测试结果:

代码语言:javascript
复制
扩展方法:
开始时间:      36800.1328125 
结束时间:      36801.96 
使用时间:      1.828125 
————————————————————————————
普通方法:
开始时间:      36801.9609375 
结束时间:      36810.26 
使用时间:      8.30078125 

50万个字符串,1.8秒和8.3秒,时间差异大约在4倍左右。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 VBA 学习 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档