VBA之正则表达式(14)-- 提取指定位数的数字

本文深入探讨VBA中使用正则表达式提取特定长度数字的方法,通过实例解析正则表达式的复杂性和匹配模式的调整技巧,适合希望提升VBA编程技能的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实例需求:只提取字符串中2位~4位的数字(无小数点),提取结果为蓝色数字。
测试字符串:6688-部门员工共10人与2019年6月成功完成销售额889966订单数689

这次的话题有些太简单了吧!?任何学习正则的同学基本上首先学会的就是这个知识点,一起回顾一下。

匹配数字有两种表示方法:

  • [0-9]
  • \d

2位~4位指的是数字字符的重复次数,可以用\d\d|\d\d\d|\d\d\d\d,重复次数比较少,组合也不多,这样还可以,其实应该用大括号\d{2,4},注意不是{2-4}

正则表达式已经有了,如果我说这次讲解到结束,接下来是掌声还是鸡蛋呢 … …

用代码测试一下效果吧。

Sub GetDigits()
    Dim strTxt As String
    Dim objRE As Object
    Dim objMH As Object
    strTxt = "6688-部门员工共10人与2019年6月成功完成销售额889966订单数689"
    Set objRE = CreateObject("vbscript.regexp")
    objRE.Global = True
    objRE.Pattern = "(\d{2,4})"
    For Each objMH In objRE.Execute(strTxt)
        Debug.Print objMH.submatches(0)
    Next
End Sub

结果如下:

6688
10
2019
8899
66
689

输出结果中为什么有889966889966怎么被五马分尸了,正则不靠谱呀!
其实这个6位数字被分为两次匹配成功,\d{4}匹配8899\d{2}匹配66
在这里插入图片描述
看来需要修改正则表达式,既然提取指定位数的数字,那么潜台词就是说提取的数字组之前和之后都不是数字,幸好记得 \D可以匹配非数字,修改一句代码如下。

objRE.Pattern = "\D+(\d{2,4})\D+"

再次测试代码,结果如下:

10

为嘛结果只有一个数字了,6688689怎么不见了。 \D可以匹配非数字是正确的,但是不能用于匹配字符串的开始位置和结尾位置,所以头和尾的数字不符合匹配模式,只能再修改匹配模式了。

最终的示例代码如下。

Sub GetDigits()
    Dim strTxt As String
    Dim objRE As Object
    Dim objMH As Object
    strTxt = "6688-部门员工共10人与2019年6月成功完成销售额889966订单数689"
    Set objRE = CreateObject("vbscript.regexp")
    objRE.Global = True
    objRE.Pattern =  "(?:^|\D)(\d{2,4})(?=\D|$)"
    For Each objMH In objRE.Execute(strTxt)
        Debug.Print objMH.submatches(0)
    Next
End Sub

结果如下:

6688
10
2019
689

终于得到了正确结果,貌似一个简单的小问题,实际上用到的知识点还真不少。


相关博文链接:
VBA之正则表达式(12)-- 格式调整
VBA之正则表达式(13)-- 字符串变换
VBA之正则表达式(14)-- 提取指定位数的数字
VBA之正则表达式(15)-- 提取数字求和
VBA之正则表达式(16)-- 提取非重复值
VBA之正则表达式(17)-- 提取多组数据(去除末尾字符)

<think>好的,我现在需要解决用户关于VBA截取字符串固定位数的问题。首先,我得回忆一下VBA中的字符串处理函数。用户提到Left、Right函数,这可能就是关键。根据引用[1],Left和Right函数可以用来截取字符串的左右部分。比如Left("字符串",位数)可以取左边指定位数的字符,Right则是右边。 然后,用户可能需要更灵活的截取方式,比如从中间某个位置开始。这时候Mid函数就派上用场了。Mid函数可以指定起始位置和位数,例如Mid("abcde",2,3)会返回"bcd"。需要确认这些函数的语法是否正确,避免出现错误。 接下来,用户可能想知道如何处理不同情况,比如字符串长度不足时的情况。比如,如果截取5位但原字符串只有3位,Left函数会返回整个字符串,而不会报错。这点需要提醒用户注意,避免出现意外结果。 另外,引用[3]中的代码示例可能有用,比如使用循环处理多个单元格的情况。例如,遍历E1:E5区域,计算最大长度后格式化输出。虽然这个例子主要是格式化数字,但思路可以应用到字符串截取上,比如统一截取固定位数并用零填充不足部分。 用户还提到正则表达式,引用[2]中提到了提取指定位数数字。如果需要更复杂的模式匹配,比如从字符串中提取连续的数字,可以使用正则表达式。比如,使用\d{4}来匹配4位数字,但可能要根据具体情况调整模式。 数据类型转换也是需要考虑的,引用[4]中的例子显示如何处理字符串和数值之间的转换。比如,用CStr将数值转为字符串,或者用CInt将字符串转为整数。这在处理截取后的字符串时可能会有用,特别是当需要进一步计算时。 现在需要把这些知识点整理成步骤清晰的回答,并提供代码示例。可能需要分点说明Left、Mid、Right的用法,每个函数举一个例子,并说明注意事项,比如位数超出时的处理。此外,补充正则表达式的方法,适用于更复杂的提取需求。 还要考虑用户可能的实际应用场景,比如处理固定格式的数据,如身份证号、电话号码等,截取特定部分。例如,身份证号的出生日期部分可能需要从第7位开始截取8位,这时候Mid函数就很合适。 最后,生成相关问题,帮助用户深入理解。例如,如何截取中间部分,如何处理动态位数,或者如何结合其他函数进行更复杂的操作。这些问题应该覆盖用户可能遇到的进一步需求。</think>在VBA中截取固定位数字符串可以通过以下方法实现,根据需求选择合适函数: ### 一、基础截取函数 1. **Left函数**(截取左侧) ```vba Dim str As String str = "ABCDEFG" Debug.Print Left(str, 3) ' 输出"ABC"[^1] ' 若原字符串长度不足则返回全部字符 Debug.Print Left("AB", 5) ' 输出"AB" ``` 2. **Right函数**(截取右侧) ```vba Debug.Print Right("ABCDEFG", 4) ' 输出"DEFG" ' 特别适用于文件扩展名提取 Debug.Print Right("report.xlsx", 5) ' 输出".xlsx" ``` 3. **Mid函数**(截取中间) ```vba Debug.Print Mid("20240501", 5, 2) ' 输出"05"(从第5位取2位) ' 三参数可省略:Mid("ABCDE",3)返回"CDE" ``` ### 二、增强处理技巧 1. **动态位数处理** ```vba Sub DynamicSubstring() Dim baseStr As String baseStr = "ID-2024-0001" ' 截取年份部分 Dim yearPart As String yearPart = Mid(baseStr, 4, 4) ' 输出"2024" ' 结合Find函数定位分隔符 Dim dashPos As Integer dashPos = InStr(baseStr, "-") Debug.Print Mid(baseStr, dashPos+1, 4) ' 输出"2024" End Sub ``` 2. **正则表达式提取(引用[2])** ```vba Sub RegexExtract() Dim regEx As Object, matches As Object Set regEx = CreateObject("VBScript.RegExp") regEx.Pattern = "\d{4}" ' 匹配4位连续数字 regEx.Global = True Set matches = regEx.Execute("订单号:20240501") If matches.Count > 0 Then Debug.Print matches(0) ' 输出"2024" End If End Sub ``` ### 三、错误处理建议 ```vba Sub SafeSubstring() Dim sourceStr As String sourceStr = "Test" ' 安全截取逻辑 Dim result As String If Len(sourceStr) >= 5 Then result = Left(sourceStr, 5) Else result = sourceStr & String(5 - Len(sourceStr), "*") End If Debug.Print result ' 输出"Test*" End Sub ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值