ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 正则表达式万能公式进化版之——“唯我独尊”

[复制链接]

TA的精华主题

TA的得分主题

发表于 2019-1-2 18:22 | 显示全部楼层 |阅读模式
本帖最后由 ggmmlol 于 2019-1-2 18:38 编辑

如果深入了解正则表达式,就会明白,正则表达式的实质是一个“表示优先匹配权限的通配符”字符串。

此前,我发表了第一版的正则表达式“万能公式”:
[\s\S]*?(eXp)|[\s\S]+
它就反应了表达式子项eXp的最高优先匹配权限:懒惰匹配“[\s\S]*?”和贪婪匹配“[\s\S]+”一前一后,前者如同心腹助手为其开路,后者则如同保镖护卫为其清扫周边残余,最终以“众星捧月”之形,彰显出eXp的绝对主角地位。
因此,我把第一版的正则表达式万能公式称为“众星捧月”版。

现在,我又提到了它的进化版“唯我独尊”版,那这个进化版到底是怎样的呢?——请看:
(赵日天)|[\s\S]+?

如果说“众星捧月”版是模拟主角eXp出场的拉轰场面而得到的表达式,那么,“唯我独尊”版则是模拟主角赵日天已经就位于主 席台时的屌炸天所得:此时无论是心腹助手还是保镖护卫,都是同一般模样地垂手肃立于其后,只有赵日天带着主角光环"()"在前面以45度角俯视台下,慷慨激昂地说:“你们这些渣渣!好好看清楚了!我、就是、八荒六合、唯我独尊,日天、日地、日空气、的、赵~日~天!”

评分

6

查看全部评分

TA的精华主题

TA的得分主题

发表于 2019-1-2 19:34 来自手机 | 显示全部楼层
我是沙发,谢谢分享

TA的精华主题

TA的得分主题

发表于 2019-1-2 20:13 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
比喻很形象!!!

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-2 22:56 | 显示全部楼层
本帖最后由 ggmmlol 于 2019-1-2 23:24 编辑

“唯我独尊”版,相对于“众星捧月”版的改进之处在于:
把“极端型”的懒惰匹配“[\s\S]*?”和“极端型”的贪婪匹配“[\s\S]+”融合为一,形成了“克制型贪婪匹配”“[\s\S]+?”,从而简化了原来的万能公式。

而简化后所得到的“唯我独尊”版万能公式,就能更明确地突显出这样的意义:
任意一个非空字符串,都可以表示为两个部分:第一部分是正则表达式子项所能匹配的部分,其余部分则是正则表达式子项所不能匹配的部分。

由此可以得到结论:正则表达式的Replace方法可以完美兼容其Execute方法,因此,在直接提取字符串中的特定内容时,Replace方法有更多选择。


评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-2 23:21 | 显示全部楼层
下面举个简单例子来说明2楼所述的结论:提取字符串常量s中的数字字符。
通常可以用排除法来解决,即替换掉s中的非数字字符,从而得到s中的数字字符。

为了简化重复的代码,假定已经预先包含了以下3句代码
  1.     Const s$ = "abc123srs289gh%$12"
  2.     Set reg = CreateObject("vbscript.regexp")
  3.     reg.Global = True
复制代码


核心的代码就是:
  1.     reg.Pattern = "\D+"
  2.     msgbox reg.replace(s,"")
复制代码

        
而用Execute方法,核心代码就是
  1.     reg.Pattern = "\d+"
  2.     sTemp = ""
  3.     For Each ma In reg.Execute(s)
  4.         sTemp = sTemp & ma.Value
  5.     Next
  6.     MsgBox sTemp
复制代码


如果按照“唯我独尊”版万能公式,用兼容Execute的Replace方法,核心代码仍然很简单:
  1.     reg.Pattern = "(\d+)|[\s\S]+?" '赵日天="\d+"
  2.     MsgBox reg.Replace(s, "$1")
复制代码

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-3 15:19 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
在5楼,对提取字符串中的数字字符,我已经提供了使用Replace方法解决此问题的2种不同的正则表达式。而实际上,还可以有第3种:
  1. reg.Pattern = "\D+|([\s\S]+?)"
  2. MsgBox reg.Replace(s, "$1")
复制代码


由此可见,在正则表达式对象的Replace方法中,可以运用:①无分组、②捕获分组,③非捕获分组这3种形式;可以利用“|”运算符两侧表达式的顺序优先级来排除或择取特定内容,以及把“|[\s\S]+?”添加在表达式的最后、以此来消耗任何非匹配的字符,从而实现对任意非空字符串的“有效的万能匹配正则表达式”。

上述的“有效的万能匹配正则表达式”,是相对于“[\s\S]+"这种毫无取舍意义的表达式而言的,因为前者能为我们择取想要的内容,而后者除了能区分字符串是否为空之外,基本上是没有实用价值的。

TA的精华主题

TA的得分主题

 楼主| 发表于 2019-1-3 15:40 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 ggmmlol 于 2019-1-3 15:51 编辑

下面这个主题帖中,由简入繁地、逐步展示了用正则表达式万能公式解决从源字符串中提取目标内容的方法。运用这些方法,甚至可以解决VBScript.RegExp正则对象所不支持的“后发零宽断言”的匹配问题,详见该主题帖2楼的附件,特此推荐阅读:
VBScript.RegExp正则对象突破后发零宽断言的限制

TA的精华主题

TA的得分主题

发表于 2019-1-3 16:32 | 显示全部楼层
怎么有种看小说的感觉,真的是屌炸天了,太牛了

TA的精华主题

TA的得分主题

发表于 2019-5-2 08:26 | 显示全部楼层

TA的精华主题

TA的得分主题

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

本版积分规则

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

GMT+8, 2024-12-27 16:58 , Processed in 0.040307 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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