ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 40750|回复: 112

[原创] 自学正则表达式过程分享——更新在63楼WORD版本!!!

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2012-6-19 16:31 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:文本处理和正则
本帖最后由 ctp_119 于 2012-7-25 07:38 编辑

自学正则表达式过程分享
1.为什么要学习正则表达式?
"    据说正则表达式处理字符串功能很强大,到底有多强大?不得而知,出自对其渴望和猎奇以外,别无它因。于是懵里懵懂的在网上收罗有关正则表达式的资料,整理之后,打印成册,一有时间就慢慢啃。如今算摸到了一点门道,于是便想和大家一起分享,因为分享是一种快乐,希望能给想学正则表达式但又无从下手的坛友共勉,分享和传递这种快乐,同时希望高手路过,能指点一二……
    第一次听说正则表达式这个概念或者名词时,那是去年学习透视表10305班里的wyf2206同学说的,他说功能强大,内容丰富。近期他又跟我提过一次,实感紧迫,不学就要落伍的感觉,于是便有了上面一幕。在此表示对其感谢!!"
2.要怎样学习正则表达式?
    任何一项新鲜事物,当你想要认识它,并且利用它时,都急切希望找到一个切入点,这个切入点就是以你现有的知识和经验去理解它,以本人来看,要有一定的vba基础,同时要有数组,自定义函数,打包封装思想,跳跃阅读等基本技能,如果你还有字典的经验就更好了,理解起来就更容易。为什么要这么说,我们不妨看个自定义函数实例:
函数功能是提取数字

  1. Function tishu(str As String) As String   '定义一个自定义函数,其中函数名称为“tishu”,str为字符串类型的形参
  2. Dim i As Integer   '定义变量i为整型
  3. Dim s As String     '定义存储器变量s为字符型
  4. For i = 1 To Len(str)     'for循环
  5.     If VBA.Mid(str, i, 1) Like "[0-9]" Then     '判断字符是否为数字,如果是就存储在s中
  6.         s = s & VBA.Mid(str, i, 1)
  7.     End If
  8. Next i
  9. tishu = s       '把存储器s字符串赋值给函数,即返回函数值。
  10. End Function
复制代码


以上代码是普通提取数字的自定义函数之一,如要了解更多方法,详情见我早期发布的http://club.excelhome.net/thread-552143-1-1.html贴子
如果以上代码都还看不懂,建议你暂时还是不要学习正则表达式,先去打打基础,再来学习(纯属个人意见)

  1. Function 提数(str As String) As String
  2. '函数功能说明:通过正则表达式提取数字。
  3. '函数参数说明:str表示要分离源字符串。
  4. '其他说明:因为正则表达式不是vba自有的对象,故此要用它就必须采用两种方式引用它,一种是前期绑定,另外一种是后期绑定,本自定义函数采用的是后期绑定(所谓的前期绑定就是手工勾选工具/引用中的Microsoft VBScript Regular Expressions 5.5)
  5. Dim reg As Object
  6. Set reg = CreateObject("vbscript.regexp")
  7. With reg
  8.     .Global = True       '搜索字符串中的全部字符,如果为假,则找到匹配的字符就停止搜索!
  9.     .Pattern = "\D"      '非数字字符的正则表达式
  10.    提数 = .Replace(str, "")       '把非数字字符替换成空字符串
  11. End With
  12. Set reg = Nothing        '清除内存中的对象变量的地址,即释放内存。
  13. End Function
复制代码

1.jpg

    以上实例,想必大家已经发现正则表达式的强大和优越性了,代码简洁,不用循环,这仅仅是正则表达式的一瞥,想要真正掌握和理解并运用它,马上跟我一起出发。

后续还有更新……………………
更新在25楼
更新在63楼word版本!!!在此非常感谢chxw68的帮助!!!

正则表达式.rar

49.99 KB, 下载次数: 703

评分

12

查看全部评分

TA的精华主题

TA的得分主题

发表于 2012-6-19 16:35 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
正则确实很强大

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:32 | 显示全部楼层
本帖最后由 ctp_119 于 2012-6-27 08:06 编辑

3.什么是正则表达式?
    我不知道大家看见“正则表达式”第一反应是什么?至少使我是想起了初中就开始学习的数学表达式。既然都是表达式我相信一定有它们相似之处。(自学的过程中一定要保持高度的联想,这样有助于我们理解新鲜事物,以后我还会加强这方面的联想和比较。)
(x+5)*3+2y是一个标准的数学表达式,一个数学表达式是由若干个"项"组成,"项"与"项"之间是加减符号相连,每个"项"之间又是由若干个因子组成的,因子与因子之间用乘除符号相连。如果我没有记错的话,小学的时候,我们叫乘数和被乘数,而到了初中,它们都叫因子了。。。
正则表达式非常类似数学表达式,都是一串符号组成。正则表达式是用一个字符串来描述一个特征,然后去验证另一个字符串是否符合这个特征,即字符串模式(pattern属性)。

点评

你把它先复制到记事本里,然后再从记事本里复制到论坛看看  发表于 2012-6-25 12:08

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:53 | 显示全部楼层
实例实测十九:        Global测试(缺省或False)        Global测试(True)
Ctp_119 ctp_119        Cp_119 ctp_119        Cp_119 cp_119
Function Global_test(str As String, pat As String, Optional bl As Boolean = False)               
Dim reg As RegExp               
Set reg = New RegExp               
With reg               
    .Global = bl               
    .Pattern = pat               
    Global_test = .Replace(str, "")               
End With               
Set reg = Nothing               
End Function               
实例实测二十:        Multiline测试(缺省或False)        Multiline测试(True)
"Ctp_119
ctp_119"        "Ctp_119
ctp_#"        "Ctp_#
ctp_#"
Function Multiline_test(str As String, pat As String, Optional bl As Boolean = False)               
Dim reg As RegExp               
Set reg = New RegExp               
With reg               
    .Global = True               
    .MultiLine = bl               
    .Pattern = pat               
    Multiline_test = .Replace(str, "#")               
End With               
Set reg = Nothing               
End Function               
实例实测二一:        Exectue测试("\d")        Execute测试("\d+")
Ctp_119 ctp_119        119119——共匹配了6次        119119——共匹配了2次
注意:这个实例加深理解"\d"和"\d+"的区别。请注意我这样做的用意!!!               

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:41 | 显示全部楼层
本帖最后由 ctp_119 于 2012-6-27 08:21 编辑

4.正则表达式有哪些符号构成?
    正则表达式是由普通字符(如:a到z,0到9等等)以及特殊字符(称为元字符)组成的字符串模式。正则表达式相当于字符串模板,将某个字符模式与所搜索的字符串进行匹配。
4-1.普通字符
    没有定义为元字符的字符都是普通字符,包括能打印和不能打印的字符,a-zA-Z0-9所有标点符号汉字以及一些符号。
4-2.特殊字符
    所谓特殊字符,就是一些有特殊含义的字符。(又开始联想了),在Excel中,哪些是特殊字符呢?大家马上会想到通配符"*"和"?"号,在查找替换中有特殊功能,功能也非常强大,除此之外,自定义筛选,函数公式中都可以应用这种特殊字符。若要查找替换文本中的"*"号,要用"~*"才能查找替换哟。记得当初把规格形如23*12*24的字符变为23×12×24着实使我犯愁,但是你一旦掌握这个技巧之后,处理这个易如反掌。。。"*"和"?"在正则表达式中也属于特殊字符哟,照样功能强大实用。请听我慢慢述来……
字符     功能说明
\          转义符,功能是将下一个字符标记为特殊字符,或一个原义字符,或一个向后引用,或一个八进制转义字符。
           例如:\f 匹配一个换页符,等价于"\x0c"或"\cL"     (表示多样性,凸显功能强大的灵活性)
                 \n 匹配一个换行符,等价于"\x0a"或"\cJ"
  1. Function 去除换行符_n(str As String) As String
  2. Dim reg As Object
  3. Set reg = CreateObject("vbscript.regexp")
  4. With reg
  5.     .Global = True
  6.     .Pattern = "\n"
  7.    去除换行符_n = .Replace(str, "")
  8. End With
  9. Set reg = Nothing
  10. End Function

  11. Function 去除换行符_x(str As String) As String
  12. Dim reg As Object
  13. Set reg = CreateObject("vbscript.regexp")
  14. With reg
  15.     .Global = True
  16.     .Pattern = "\x0a"
  17.    去除换行符_x = .Replace(str, "")
  18. End With
  19. Set reg = Nothing
  20. End Function
  21. Function 去除换行符_c(str As String) As String
  22. Dim reg As Object
  23. Set reg = CreateObject("vbscript.regexp")
  24. With reg
  25.     .Global = True
  26.     .Pattern = "\cJ"
  27.    去除换行符_c = .Replace(str, "")
  28. End With
  29. Set reg = Nothing
  30. End Function
复制代码
2.jpg

TA的精华主题

TA的得分主题

发表于 2012-6-19 16:45 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
支持一下,感谢楼主的一片好心

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:46 | 显示全部楼层
本帖最后由 ctp_119 于 2012-6-27 08:28 编辑

    注:如果你还不太理解,没有关系,只要你有个初步印象,相信读书百遍,其义自现,打包封装函数思想,这种意识始终贯穿自学全过程.
  1. '以下是一个通用自定义函数。
  2. Function exReplace(str As String, repstr As String, pat As String)
  3. '正则表达式替换函数
  4. '参数说明:str表示原字符串,repstr表示将要替换的字符串,pat表示样式

  5. Dim reg As Object
  6. Set reg = CreateObject("vbscript.regexp")     '创建一个正则表达式变量
  7. With reg
  8.     .Global = True        '搜索字符串中的全部字符,如果为false表示一找到匹配的字符就停止搜索。
  9.     .MultiLine = True     '设置多行搜索匹配
  10.     .Pattern = pat       '设置样式
  11.     exReplace = .Replace(str, repstr)     '执行替换
  12. End With
  13. Set reg = Nothing       '释放对象内存变量
  14. End Function
复制代码
提示:为了好讲解,弄了一个通用自定义函数。以下全用这个函数来测试,敬请注意。
                 \cx 匹配由x指明的控制字符,如上例"\cJ"
                 \r 匹配一个回车符,等价于"\x0d"或"\cM"
                 \s 匹配任何空白字符,包括空格,制表符,换页符等等,等价于"[ \f\n\r\t\v]" (注意:"["后面有个空格)
                 \S 匹配任何非空白字符,等价于"[^ \f\n\r\t\v]"      (注意:"[^"后面一个空格)

3.jpg

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:46 | 显示全部楼层
本帖最后由 ctp_119 于 2012-7-7 07:32 编辑

    不知你是否已经注意到\s和\S刚好反义,仅一个大小写的区别,这是一种规则,敬请注意,同时表示反义的另一种方式是正则表达式前面加"^"。后面还会有具体详实的表述,在此只是一种提示,希望自学时要多留意观察和比较。
                 \t 匹配一个制表符,等价于"\x09"和"\cI"
                 \v 匹配一个垂直制表符,等价于"\x0b"和"\cK"
"^          匹配字符串开始位置,如果设置了Regexp对象的Multiline属性,也匹配""\n""或""\r""之后的位置。若在方括号""[""
           中使用,表示不接受该字符集。"
注意与"["后面的"^"区别哟,它们的意义绝然不同。一个是匹配字符串开始位置,一个是取反。
$          匹配字符串结束位置,如果设置了Regexp对象的Multiline属性,也匹配"\n"或"\r"之前的位置。
    怎么理解"^"和"$"呢?例如:"^a"能匹配字符串"abcd"中的"a",而"^b"则不能匹配字符串"abcd"中的"b";同理可得:"d$"能匹配字符串"abcd"中的"d",而"c$"则不能匹配字符串"abcd"中的"c"。
[img]file:///C:\Documents and Settings\Administrator\Application Data\Tencent\Users\84562532\QQ\WinTemp\RichOle\T[[7F78GL~_L76_{W7IQL[9.jpg[/img]

T[[7F78GL~_L76_{W7IQL[9.jpg

    自学的过程中,难免会有一些自己暂时无法理解的东西,这时候通常需要我们跳跃性阅读,暂时把问题放一放,继续阅读下文,或再找相关资料辅助我们理解,或干脆通过一个实例去验证它。
*          匹配前面子表达式0次或多次。例如:"to*"能匹配"t",也能匹配"to",甚至能匹配"toooooo"。等价于{0,}

2.jpg
?          匹配前面子表达式0次或1次。例如:"do(es)?"可以匹配"do"或"does"中的"do"。等价于{0,1}

3.jpg
"+          匹配前面子表达式1次或多次。例如:""to+""可以匹配""to""中的""o"",也可以匹配""too""中的""oo"",但是不能匹配""t""。
           等价于{1,}。"
"    敬请注意以上三个特殊符号的区别,要深刻理解,要怎样才能做到深刻理解呢?学习计算机语言,一定要动手,仅仅动脑是不够的,切记:在输入代码时记忆,在调试代码中理解。
    *,+和?限定符都是贪婪的,这个“贪婪”二字用的精妙。一开始不理解,一般是人才知道贪婪,什么符号也贪婪,再思索,原来运用了通感的修辞手法。给它拟人了。。呵呵,这是汉字的魅力……
    三个符号的等价理解:{0,}理解为数学区间的表示,(0,+∞);{0,1}理解为(0,1);{1,}理解为(1,+∞)。这样一来,既记住了又理解了。"
{n}        n是一个非负整数,匹配精确的n次。如:"e{2}"只能匹配beer中的"ee",而不能匹配"be"中的"e"。
"{n,}       n是一个非负整数,至少匹配n次。例如:""e{2,}""不能匹配""ber""中的""e"",但能匹配""beer""中的""ee"",当然它也能匹
           配""beeeeeer""中的所有""e""。""e{1,}等价于""e+"";而""e{0,}""等价于""e*""。"



TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:47 | 显示全部楼层
|          指明两项之间的一个或选择。如实例实测七中的".|\n"便是。若要匹配该字符本身请用"\|"。
(?:pattern)匹配pattern,但不获取匹配结果,是一个非获取匹配,不存储供以后使用。例如:"industr(?:y|ies)就比
           "industry|industries"更加简洁。
注释:pattern表示一个正则表达式。上例中pattern就是"y|ies"。
(?=pattern)正向预查,在任何匹配pattern的字符开始处匹配查找字符串,是一个非获取匹配,不存储供以后使用。例如:
           "Windows (?=95|98|NT|2003|xp)"能匹配"Windows 2003"中的"Windows",但不能匹配"Windows 3.1"中的
           "Windows"。
(?!pattern)负向预查,在任何不匹配pattern的字符串开始处查找字符串,是一个非获取匹配,不存储供以后使用。例如:
           "Windows (?=95|98|NT|2003|xp)"能匹配"Windows 3.1"中的"Windows",单不能匹配"Windows xp"中的"Windows"
x|y        匹配x或y。例如:"t|fool"能匹配"t"或"fool";而"(t|f)ool"则匹配"tool"或"fool"。实例实测九已经应用。
[xyz]      表示字符集合,匹配所包含的任意一个字符。(在中括号里面的字符都是原意字符,区分全角半角)
[^xyz]     表示负字符集合,匹配未包含的任意字符。(这里的"负"不是正负的负,是表示相反的意思。)
实例实测十一:
"[.|?]测试
"[的ad]"测试
"[^的ad]"测试
32.5是对的吗?ab的cdafde
325是对的吗ab的cdafde
32.5是对吗?bcfe
的a的dad
[a-z]      表示字符范围,匹配指定范围内的任意字符。如"[a-z]"可以匹配"a"到"z"范围内的任意小写字母。
[^a-z]     同理,表示负值字符范围,匹配任何不在指定范围内的任意字符。
\b         匹配单词的边界,也就是指字符串与空格间的位置。注意与"^"或"$"特殊符号的区别。
\B         匹配单词的非边界,也就是指字符串中间的位置。
实例实测十二:
"\ba|a\b"测试
"er\B"测试("\Ber"相同)
"^ab"测试
"a$"测试
abdcereafjherca aberada
bdcereafjherc berad
abdceafjhca abada
dcereafjherca aberada
abdcereafjherca aberad
    请深刻比较和理解"\b"和"^"或"$"的区别。注意,在描述"\b"和"\B"的时候用的是单词,而不是字符串,测试表明"\b"匹配的是字符和空格间的匹配,而"^"或"$"匹配的是字符串首尾的字符和空白之间的位置。有相同点和不同点哟!!!
\d         匹配一个数字字符,等价于"[0-9]"。
\D         匹配一个非数字字符,等价于"[^0-9]"。
实例实测十三:
"\d"测试
"\d+"测试
"\D"测试
a15b289fji86425846f
abfjif
abfjif
1528986425846
    测试结果相同,但是它们的运行机理却截然不同,谁效率最高?内部是怎样工作的,这就看你对限定符"+"的理解了。
\w         匹配包扣下划线在内的任何单词字符,等价于"[a-zA-Z0-9_]"。
\W         匹配任何非单词字符,等价于"[^a-zA-Z0-9_]"。
实例测试十四:
"\w"测试
"[a-zA-Z0-9_]"测试
"\W"测试
ctp_119江西乐平
江西乐平
江西乐平
ctp_119

TA的精华主题

TA的得分主题

 楼主| 发表于 2012-6-19 16:48 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
\xn        匹配n,其中n是十六进制转义值。十六进制转义值必须为确定的两个数字长。例如:"\x41"匹配"A",而"\x041"匹
           配的是"\x04|1"。正则表达式中可以直接使用ASCⅡ编码。
\num       匹配num,其中num是一个正整数,对所获取的匹配的引用。例如:"(.)\1"匹配两个连续的字符。
实例实测十五:
"(.)\1"测试
"(.)(.)\2"测试
ctp_119 aabbbcccc
ctp_119 aac
ctp9c
实例实测十六:
"(.{1,})\1"测试
"(.{2,})\1"测试
ctp_119 abab abcabc
ctp_9  
ctp_119  
\n         标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用;否则,如果n为八
           进制数字(0-7),则n为一个八进制转义值。
9
5.操作符的优先级
    相同级别的优先级是从左到右进行运算,不同级别的优先级先高后低。各种操作符的优先级从高到低如下:
(为了更好的理解优先级,先看看数学表达式的优先级,我们知道(),[],{},×或÷,+或-)
操作符                 说明
\                      转义符
(),(?:),(?=),(?!),[]   圆括号和方括号
*,+,?,{n},{n,},{n,m}   限定符
^,$,\n                 位置和顺序
|                      "或"选择。
构造正则表达式和构造数学表达式的方法是一样的,请注意类比。
6.这些符号组成的正则表达式到底是怎样工作的?(这才是我们最为关心的,是我们的终极目标,前面讲的都是一些基础,要素,或更直白点讲,是构成正则表达式的素材和规则)
    说到底,VBA的学习就是对象的学习,而对象的学习又集中到对象的方法和属性的学习。正则表达式也不例外,本身也是一个对象,并且是外来对象,所谓的外来,具体表现在两个方面:第一,VBA本身没有这个对象,是第三方提供的ActiveX控件,第二,要引用它时必须要先绑定(前期绑定或后期绑定)才能引用。
Function tihuan(str As String, st As String, pat As String) As String
'本函数采用的是前期绑定,即勾选microsoft VBScript Regular Expressions 5.5
'采用前期绑定的优点是引用改对象时,自动列示该对象的方法和属性,非常适合记不住该对象属性和方法的单词的学员
'缺点是要事先手动"工具/引用,勾选Microsoft VBScript Regular Expressions 5.5" , 如图①所示。
'功能是在字符串str中找到匹配pat样式,之后用st字符串去替换掉pat样式的字符串
Dim reg As New VBScript_RegExp_55.RegExp   '定义一个对象变量,并第一次引用时初始化reg为Regexp对象变量,具体表现是分配内存地址。
'(Dim reg As RegExp    '定义一个对象变量为Regexp。)
'(Set reg = New VBScript_RegExp_55.RegExp      '立即初始化分配内存地址。)
'上面两句和第一句作用是一样的,不同的写法而已。
With reg
    .Global = True
    .MultiLine = True
    .Pattern = pat
    tihuan = .Replace(str, st)
End With
Set reg = Nothing
End Function
注释:这个函数和前面Exreplace函数功能是一样的,在这里只是用来说明前期绑定和后期绑定的区别。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-23 22:37 , Processed in 0.054091 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表