ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[原创] 5句话彻底理解"位置",让你的正则表达式水平突飞猛进!

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2024-9-10 22:58 | 显示全部楼层 |阅读模式
本帖最后由 龙逸凡 于 2024-9-11 11:17 编辑


第一句
在正则表达式眼中,字符串由位置和字符组成。正则表达式就是去匹配字符或位置。
比如:字符“Excel”就是由字母E、x、c、e、l,以及他们之间的位置、前、尾等六个位置组成。


看不懂?
没关系,我们后文会围绕这一点进行详细阐述。

第二句
字符串的位置有字符串的开始、结尾、单词的边界、除了单词边界的其他位置。
匹配位置的元字符有^、$、\b、\B、\A、\Z、\z

下面我们一个个来介绍
1、字符串的开始,用^表示,字符串结尾,用$表示

示例:
将字符串的开头或结尾“替换”为@

注意,字符串的开头和结尾位置是聚宝盆,不管你是替换它,还是不替换它,它就在哪里,不增不减。
按常理,我们将某字符替换后,它应该就不存在了。但开头和结尾这位置始终都在。我们用REGEXP将开头、结尾位置替换为@后,还可在外面套一层REGEXP再去替换,只要你有耐心,可以一直替换,无穷无尽。
原理后面再做解释。

2、表示字符串的开始结尾还可用比较冷门的\A、\Z、\z
\A 表示字符串的绝对开头,也就是我们通常理解的一个字符串的开始。^ 一般情况也表示字符串的开头,但在多行模式下时,表示每行的开头。
也就是说,不是多行模式时,他们是一样的。
如下图:

但在多行模式下,\A表示字符串的绝对开头,而^表示每行的开头。

一般情况下,$、\Z、\z都表示字符串的结尾。
$ 表示字符串的末尾,或者在字符串末尾的换行符之前。在多行模式时,表示每一行的结尾。\z 表示字符串的绝对结尾。后面不会有任何字符(包括换行符)
\Z 匹配字符串的末尾,或者在字符串末尾的换行符之前。
说明:
下图B1单元格的“Excel偷懒的技术”后面有两个换行符。

\b 表示单词边界。
单词是指由连续相邻的字母、数字或下划线组成的字符序列。
\B 是除单词边界之外的其他位置
如下图B4单元格的公式
=REGEXP(B1,"\b",2,"@")
将B1单元格单词的左右边界替换为@符号。

实战案例:




点评

引用******图片不可见,改直接上传  发表于 2024-9-11 09:45

评分

15

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-10 23:00 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 龙逸凡 于 2024-9-11 11:23 编辑

上一篇文章我们说了:
在正则表达式眼中,字符串由位置和字符组成。正则表达式就是去匹配字符或位置。

对于正则的初学者来说,匹配位置通常比匹配字符更难理解一些。所以,这五句话都是围绕位置来讲解的。
接上篇,我们继续

第3句
位置相当于空字符
上一篇文章我们介绍了字符串是由字符和位置组成,
比如字符串“Excel“每个字符前后都有一个位置。

我们通常说“位置”,一般认为它是有顺序的,但正则表达式中的“位置”并不能用第几个位置来指称。我们可以将正则表达式中的位置理解成空字符。
在Excel中文本需要用双引号括起来,双引号中间没有内容,就是空字符。用""表示空字符。也就是说,在正则表达式眼中“Excel”相当于:
""+E+""+x+""+c+""+e+""+l+""

来测试一下是否如此
证明1:
用REGEXP的替换模式,将位置替换为@字符看效果
=REGEXP(B1,"",2,"@")

插入字符的更多写法见文后的图片。

证明2:
提取字符串中的所有字符(含位置)
公式:
=REGEXP(B1,".*?")

正则表达式解释:
正则表达式.*?是一个非贪婪(懒惰)匹配的模式,它的含义是:
.:匹配任意单个字符(除了换行符)。
*:匹配前面的字符零次或多次,即匹配任意数量的字符。
?:问号“?”放在*星号和+加号等量词后是一个非贪婪修饰符,表示尽可能少地匹配字符。
要点:
  • 非贪婪的 .*? 会尝试匹配最少的字符,所以在第一次应用时,它会首先去匹配零个字符(即不匹配任何字符),零个字符匹配不上,再匹配1个字符……。当匹配零个字符时,就会将位置(空字符)匹配上。
龙逸凡:这堆文字看起来比较绕、比较上头,理解后会大大提升你的正则……
偷懒读者:打住!说关键的,有什么用?
龙逸凡:我们来看一个实战案例,一个你肯定用得上的案例。用这方法可以在每个字符间插入一个你喜欢的符号,比如:长得象雪花的星号*。
公式:
=REGEXP(B3,"",2,"*")

偷懒读者:然后呢?拎瓶雪花勇闯天涯?
龙逸凡:不,这些雪花能帮你找到意中人去风花雪月年年暮暮朝朝。将上面的公式放到VLOOKUP函数的第一参数,实现你梦寐以求的查找功能:根据不连续简称查全称
偷懒读者:???

龙逸凡:看图说话

偷懒读者:哇……!太棒了,的确梦寐以求!这公式是我一直寻找的。众里寻它千百度,蓦然回首,公式却在,偷懒公号处。只是,我看不懂这公式,能否解释一下?龙逸凡:星号在正则表达式中是量词,表示0个及多个,但在Excel函数中,它是通配符,表示任意多个任意字符(但不代表星号本身)。函数REGEXP(B3,"",2,"*")的计算结果是“*偷*懒*1*”。用它做Vlookup函数的第一参数,意思是在去查找符合这样规则的字符串:
在“偷”、“懒”,“1”三个字符中间有若干个其他字符的文本。
在E列的名称列表中,符合这种格式的文本就是“《“偷懒”的技术1:打造财务Excel达人》”。所以VLOOKUP将它做为查找结果。
偷懒读者:明白了,很巧妙。
龙逸凡:在理解“位置就是空字符”后,大家应该就能理解正则表达式专业术语“零宽断言”中的“零宽”了。位置相当于空字符,它是没有宽度(字符数)的,所以说是零宽。
偷懒读者:我好象理解“位置就是空字符”了。
龙逸凡:不,你没有。
偷懒读者:为什么?
龙逸凡:来做个小测试,公式=REGEXP("Excel","^^^",2,"@"),将字符串开始的位置(连续三个)替换为@符号,其计算结果是什么?备选答案:
A、会显示出错;B、@@@Excel;C、@Excel
偷懒读者:字符的开始处只有一个,用三个^去匹配肯定匹配不上,不够用啊。所以肯定是A,当然,不排除是B。
龙逸凡:我们看完第五句话再来做这道题。先看第四句。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-10 23:01 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 龙逸凡 于 2024-9-11 11:44 编辑



第四句
正则表达式还可用字符来确定位置,比如“前面是XX(在XX后面)”、“前面不是XX(不在XX后面)”、“后面是XX(在XX前面)”、“后面不是XX(不在XX前面)”。
用此方法时,请屏蔽掉那些装逼拗口晦涩难懂的专业术语“零宽断言、正向预查、反向预查、顺序肯定环视、逆序否定环视、零宽度正预测先行断言、零宽度负回顾后发断言”。
正则表达式写法及其作用见下表:

助记方法:
  • ? 通常用于表示是某种模式,比如上一篇文章用到的(?m)多行模式、还有(?i)忽略大小写的模式。
  • = 是;
  • ! 表示排除、否定,不是;
  • < 指向左边,也就是前面
合起来看
“?<=”左边是,也就是“前面是,在XX后面”,
“?<!”左边不是。
龙逸凡:是不是很好理解?
偷懒读者:理解了,不会再用错了

案例:
来看个小案例深入理解一下。比如字符串"Excel"中X和C之间的那个位置,我们可以描述为“在C前面”或“在x后面”

老办法,还是用正则函数的替换模式将“位置”替换为@符号,让位置可视化,更直观。
需求:
在字母"c"之前插入一个@号:
公式:
=REGEXP(B1,"(?=c)",2,"@")
在字母"x"之后插入一个@号
公式:
=REGEXP(B1,"(?<=x)",2,"@")

字符串"Excel"的其他位置,可以描述为不在c之前,不在x后。
在“不在c前面”的位置插入一个@号
公式:
=REGEXP(B1,"(?!c)",2,"@")
在“不在x后面”的位置插入一个@号
公式:
=REGEXP(B1,"(?<!x)",2,"@")

来看几个实战案例吧
案例1:
提取“本”字前面的册数、提取“元”字前面的金额(含小数点),将其转为数值然后求和。

龙逸凡:Regexp函数是文本函数,运算结果是文本,前面放两个负号,负负得正,四则运算一下,即可将文本数字转为数值,以方便求和。
偷懒读者:这个知识点我知道。我不明白的是字符串中的“234本”,只有4后面有“本”字,2和3后面并没有“本”字,它们为什么能提取出来。
龙逸凡:“\d+(?=本)”的意思是:前面是若干个连续数字,后面跟了个“本”字,也可理解为:“本”字前面的若干个连续数字。
偷懒读者:哦……终于明白了。

案例2:
提取中文逗号和#号之间的内容

案例3:
判断是否姓“龙”
=REGEXP(B3,"^(?!龙)",1)

^ 是开始的位置
(?!龙) 后面不是“龙”字
^(?!龙) 合起来就是“开始位置后不是“龙”,也就是不姓“龙”。

案例4:
提取主办、主管人员的姓名(不带职位)
公式:
=REGEXP(B1,"[一-龟]+(?=主办|主管)")


案例5:
提取B列字符串中的数量
公式:
=REGEXP(B2,"(?<=\*)\d+")
=REGEXP(B2,"\d+(?=[桶缸罐坛]|$)")

案例6:
给银行账号每4位添加一空格

看起来好象没问题,如果换成逗号就会发现有问题
从前往后添加逗号的公式:
=REGEXP(B1,"(\d{4})",2,"\1,")
从后往前添加逗号的
=REGEXP(B1,"(?=(\d{4})+$)",2,",")

那怎么解决呢?
需要用到第五句话的知识。

评分

2

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-9-10 23:02 | 显示全部楼层
本帖最后由 龙逸凡 于 2024-9-11 13:35 编辑

第五句
字符只能被匹配一次,位置可以被多次匹配。
比如下面的示例:
公式:
=REGEXP(B1,".e",2,"@")

B1单元格内容是“eel”,用正则表达式".e"去匹配,首先用"."去匹配,第一个"e"能匹配上,被消耗掉(后面的正则表达式就不能再匹配此字符了)。然后用正则表达式中的"e"去匹配字符串中的第二个"e",也能匹配上。
但是,位置被匹配后,并不会被消耗掉,还能被其他的正则表达式匹配。
比如公式:
=REGEXP(B1,"^(?=E)\A",2,"@")

首先用^去匹配,会被匹配到字符串的开头,这位置不会被消耗掉。
接着,用(?=E)去匹配,匹配到的还是"E"前面的位置,也就是字符串的开头。
接着,又去用\A去匹配,这是字符串的绝对开头,匹配的还是字符串的开始处。
也就是说字符串的“开始”这个位置被匹配了三次。
现在再来做=REGEXP("Excel","^^^",2,"@")这道题,你就知道其计算结果是“@Excel”了。

龙逸凡:现在你终于知道为什么找不到喜欢的人了吧?
偷懒读者:为啥?
龙逸凡:就三个备选答案,你都能完美地错过正确答案,你还指望能从14亿中准确地找到你喜欢的人?
偷懒读者:



我们来看看这个知识点的实战应用案例

案例7:
在前面的案例6给银行账号从后往前每4位添加逗号,当账号长度是4的倍数时,会在最前面多出一个逗号。如下图

如何避免这种情况呢?
我们只需在原正则表达式的基础上,再添加一个位置判断:
当是行首时,就不添加逗号。
换另一种表达:
当不是行首时,才添加逗号
完整的条件是:
从后往前,每四位所在的位置,并且不是行首的位置处,加一个逗号。
公式:
=REGEXP(B33,"(?!^)(?=(\d{4})+$)",2,",")

扩展案例1:给字符串中的数字添加千位分隔符,但不能给年份添加。
公式:
=REGEXP(B1,"(?<=\d)(?=(?:\d{3})+($|[^\d年]))",2,",")

扩展案例2
密码校验:由数字字母下划线组成,长度不少于八位。且至少一个大写字母、一个小写字母、一个数字
公式:
=REGEXP(B5,"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)\w{8,}$",1)

知识点:
  • 至少包含1个大写字母:
(?=.*[A-Z])
  • 至少包含1个小写英文字母
(?=.*[a-z])
  • 至少包含1个数字
(?=.*[0-9])

扩展案例3
判断字符串中是否不包含XXX
公式
=REGEXP(B5,"^((?!52|1234).)*$",1)

知识点:
  • 不包含XXX的正则表达式
^((?!字符串).)*$
利用位置可以被多次匹配的特性,还能解决“前面是 (?<=...)” 和“前面不是 (?<!...)”位置匹配模式下,不能使用不确定量词的问题。

案例7:
B列是一些订单数据,现在要求在其金额后添加“元”字,但不能在编号数字后添加“元”,已有“元”的也不再能添加。
分析:
……
完整的公式:
=REGEXP(B3,"(?<!编[号码])(?<!编[号码][::])\b([0-9.]+)(\r|\n|$)",2,"\1元\2")
第五句不太好理解,大家慢慢消化。
附上在字符间各种花式插入星号的正则表达式

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-9-11 06:31 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-9-11 08:55 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-9-11 09:07 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-9-11 09:18 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-9-11 09:50 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
龙逸凡 发表于 2024-9-10 23:02
第五句
字符只能被匹配一次,位置可以被多次匹配。

感谢楼主, 但图片挂了,看不到!

TA的精华主题

TA的得分主题

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

本版积分规则

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

GMT+8, 2024-12-25 15:21 , Processed in 0.055323 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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