在之前的一篇文章中介绍了环视,参见文末的参考资料[1]。环视的一个经典应用是添加千分位。添加千分位的一个正则表达式如下:
代码语言:javascript复制(?<!.d )(?<=d )(?=(d{3}) (?!d))
代码语言:javascript复制文本:12345678.12345678
替换文本:,
结果:12,345,678.12345678
上面的正则表达式可以拆分成以下三个部分:
(1)?<!.d
,逆序否定环视。所在位置的左侧不能出现小数点加数字。这是为了保证小数部分不会添加千分位。
(2)?<=d
,逆序肯定环视。所在位置的左侧只有数字。这是为了保证在整数部分添加千分位。
(3)?=(d{3}) (?!d)
,顺序肯定环视、顺序否定环视。所在位置的右侧,连续数字字符的个数是三的整数倍;并且其后跟随一个非数字字符(小数点.
,或者结束标识符$
,等等)。
VBA中通常使用的是VBScript正则(vbscript.regexp
),不支持逆序环视。因此,上述的正则表达式在VBA中无法使用,现在通过一种变通的方法来实现这个需求。
1 试错
(1)对于整数,可以使用如下的正则表达式:
代码语言:javascript复制(d)(?=(d{3}) $)
代码语言:javascript复制文本:123456789
替换文本:$1,
结果:123,456,789
从右向左每三位划分为一组,那么末端三位数字的右侧一定就是行的结束标识了;此外,提取三位数字组合左侧的一位数字作为匹配组,用于正则替换。
(2)对于包含小数的字符串,可以使用如下的正则表达式:
代码语言:javascript复制(d)(?=(d{3}) .)
代码语言:javascript复制文本:1234576.7898
替换文本:$1,
结果:1,234,576.7898
三位数字从小数点开始向左数,所以末端三位数字的右侧就是小数点。
(3)尝试将前面的两个正则表达式合并,得到如下的正则表达式:
代码语言:javascript复制(d)(?=(d{3}) ($|.))
代码语言:javascript复制文本1:123456789
替换文本:$1,
结果:123,456,789
代码语言:javascript复制文本2:1234576.7898
替换文本:$1,
结果:1,234,576.7,898
针对包含小数的字符串,合并之后的正则表达式的运行结果并不理想。结束标识$
本意是希望用来匹配整数的结尾,但是小数部分也可能匹配到,所以小数部分也添加了千分位,这显然是不对的。
(未完待续)
参考资料:
[1] 正则表达式:断言(环视)
[2] 正则表达式在线测试(https://c.runoob.com/front-end/854/?optionGlobl=global)
[3] 正则测试(https://tool.chinaz.com/regex)
[4] VBA之正则表达式(9)-- 添加千分位(1/3)(https://blog.csdn.net/taller_2000/article/details/89784517)