ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] [技巧]正则表达式万能公式应用实例:在一个字符串内按分隔符提取不重复项

  [复制链接]

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-7-21 22:31 | 显示全部楼层
dgenson 发表于 2019-7-12 13:10
大师太牛了,你这短短10几个字符我研究了几天还没弄懂,现向您请教几个问题,见下图,
1.在替换时用$2$3 ...

第一个Item中有四个银行,是因为这个表达式的前面有".*?",这一部分匹配了前3个银行。如下图所示。

注意,使用正则的Execute方法,只需要用匹配目标字符的表达式(eXp)就可以了,因此,如果是Execute方法,则不要加上".*?"
而要使用正则的Replace方法,那么,正则表达式需要完整匹配整个源字符,因此,它的万能公式就是:
.*?(eXp)|.+
它的意义就是:每一个源字符串,都可以看做是由若干段组成,其中每一段的开始位置有若干个非目标字符(由.*?匹配),然后是目标字符,由捕获分组(eXp)取得;而eXp不可能总是恰好匹配到源字符的结束位置,这时,剩余的若干个字符由分支选择中优先级较低的"|.+"来负责包圆儿匹配。

因此,正则的Replace方法,就是要让源字符串中的每一个字符都被正则表达式所匹配,而在表达式中,根据目标字符的特点,使用捕获与非捕获来进行取舍。 分析.png

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-7-21 23:38 | 显示全部楼层
dgenson 发表于 2019-7-12 13:10
大师太牛了,你这短短10几个字符我研究了几天还没弄懂,现向您请教几个问题,见下图,
1.在替换时用$2$3 ...

另外,关于$3的捕获内容为空的问题,这是正则表达式的Execute方法和Replace方法匹配结果上面存在细微的区别:

本例中,表达式"(^|;)([^;]+)(?=;*$|(;))(?!.*;\2(;|$))"有4个捕获分组,但是第3个和第4个捕获分组,都分别嵌套在一个“零宽断言”的分组里,这种情况下,Execute方法得到的内容受零宽断言的限制,总是修正为空字串;而Replace方法则会在每个匹配成功瞬时不做任何修正地应用匹配的内容。

TA的精华主题

TA的得分主题

发表于 2019-7-24 22:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
360截图20190724220810948.jpg LZ您好,想知道这两个式子中,红色部分的使用情况,因为发现删除之后对结果也没有影响。
那么,有没有一种情况,必须使用后面的红色部分,删除后结果立马和原来不同?

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-7-25 18:03 | 显示全部楼层
zhanglei1371 发表于 2019-7-24 22:09
LZ您好,想知道这两个式子中,红色部分的使用情况,因为发现删除之后对结果也没有影响。
那么,有没有一种 ...

第1个表达式中,开始位置的";+$|"与末尾的"|.+"在本例中是等效的,因此可以去掉一个。前面的帖子里已经解释过。
第2个表达式中,"|^;+"的作用已经隐含于它前面的分支表达式中,也是可以去除的。但后面的"|;+?(;|$)"不应去除,否则,当源字符串的中间有连续2个以上的";"或末尾出现";"时,所得结果的中间或结尾也会有多余的分号。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-7-25 18:38 | 显示全部楼层
本帖最后由 ggmmlol 于 2019-7-25 18:39 编辑

此外,对比两个公式,可以看出:
公式一可以完美去除多余的分隔符,而公式二的结果中,有一些的开始位置会有一个多余的分号。
这是因为公式一,是采用捕获目标项字符和分隔符的方法,可以灵活地捕获需要的分隔符。
而公式二,是采用的删除非目标项和分隔符的方法,但为了避免分界不准确而删除了过多的内容,它需要在保留项的字符前面保留有至少一个分隔(一个分号或字符的开始位置),当第一个保留项不是恰好在源字符串的开始位置出现时,它前面必须有一个分隔符分号要保留下来。

TA的精华主题

TA的得分主题

发表于 2019-7-25 23:10 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2019-8-27 10:02 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
正则表达式应用很广,它灵活度高的查找方式被人们喜爱,正则表达式又是一种独立的语言,它有自己独立的规则,这种规则如魔如幻、高深莫测。论坛中有不少正则表达式的启蒙帖,在正则表达式实际运用的帖子中,不乏用得好用得妙的案例,但如本帖一样能把思路解析得如此明白的,不多见,让人知其然,更知其所以然。按分隔符提取不重复项,不少人还是愿意使用Split(),但有一群人,将会从本帖开始,对正则表达式产生强烈的兴趣,找到学习、研究正则表达式的方向和方法,在此,我代表受益于本帖的人向ggmmlol表示感谢。

TA的精华主题

TA的得分主题

发表于 2019-8-31 13:03 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
精品果然是理解不了.....

TA的精华主题

TA的得分主题

发表于 2019-9-8 23:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
ggmmlol 发表于 2019-7-5 21:41
按我提出的正则表达式万能公式:.*?(eXp)|.+
这里的eXp是一个正则表达式变量,在本例中,它需要直接匹配 ...

(?=;*$|(;))用的好!

TA的精华主题

TA的得分主题

发表于 2019-9-22 23:42 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-22 05:18 , Processed in 0.033932 second(s), 9 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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