正则表达式的基础外壳函数(wps版):
REGEXP函数是基于正则表达式,对复杂文本进行匹配、提取和替换的函数。
基本语法结构:
REGEXP(原始字符串,正则表达式,[匹配模式],[替换内容])
匹配模式是可选项,0或忽略表示提取,1表示判断是否包含,2表示替换。
替换内容是可选项,仅在匹配模式为2时有效,用来替换匹配的内容。
我们通过编写不同的正则表达式来实现不同的复杂需求。
最近自学REGEXP函数的正则表达式知识,总是从资料中看到“零宽断言”的字眼,对它的概念是百思不得其解。今天我们就下决心再次深入细致的了解一下,毕竟入门正则表达式,是绕不开它的。
零宽断言(Lookaround Assertions)用于匹配符合条件的位置而非具体字符,不占用匹配字符长度。
零宽断言分为4种类型。
类型、符号以及功能:
(?=) 正向先行断言
右侧必须出现指定模式
通俗讲:必须以某固定字符结尾
(?!) 负向先行断言
右侧不得出现指定模式
通俗讲:必须不能以某固定字符结尾
(?<=) 正向后行断言
左侧必须出现指定模式
通俗讲:必须以某固定字符开头
(?<!) 负向后行断言
左侧不得出现指定模式
通俗讲:必须不能以某固定字符开头
当然了,概念固然重要,因为它是我们灵活运用零宽断言的前提。但如果我们再结合具体的案例,就会对使用这个零宽断言起到事半功倍的效果。
我们通过下面一个例子理解(?=) 正向先行断言与(?<=) 正向后行断言。
如下图所示:
我们想要提取A2单元格括号内容,但最终不显示括号符号。也就是说括号内容是:“(red)”,“(green)”,“(blue)”,但最终不要显示括号为:“red”,“green”,“blue”。
我们这样提取括号内容。
输入公式:
=REGEXP(A2,"\(.+\)")
\:代表转义符。
\(:表示转义左括号。
\):表示转义右括号。
因为括号(英文半角下)在正则中有其独特的含义,这里表示真正的普通括号,为了避免使用冲突,须要转义。
.:点号代表任意的单个字符(除换行符)
+:代表重复前面元素的1次或多次。
.+:表示任意的多个字符。
\(.+\):完整表示括号里面的任意的多个字符。
此时默认贪婪模式匹配到多余的内容。
转换为懒惰模式:
=REGEXP(A2,"\(.+?\)")
在量词符“.+”后面加上一个问号?,使其变成懒惰模式。这样它会在匹配到第一个符合要求的数据“(red)”后,停止工作,自动去匹配下一个符合要求的数据“(green)”,然后再次停止工作,自动匹配最后一个符合要求的数据“(blue)”,直至全部匹配完结束。
此时虽然匹配结束,但得到的括号内容并没有去掉括号。
重点来了,我们使用(?=) 正向先行断言
=REGEXP(A2,"\(.+?(?=\))")
右侧必须出现指定模式,比如说匹配到的其中一个括号内容:“(red)”,而“(red”的右侧必须出现指定的右括号“)”,但不占用匹配字符长度,即不显示“)”。
所以我们对表达式中右括号“\)”加上正向先行断言“(?=\))”,即内容的右侧必须是右括号但不显示它,这样就相当于去掉了右括号。
我们继续使用(?<=) 正向后行断言
=REGEXP(A2,"(?<=\().+?(?=\))")
左侧必须出现指定模式,比如上一步得到的匹配结果是去掉右括号的内容:“(red”,而“red”的左侧必须出现指定的左括号“(”,但不占用匹配字符长度,即不显示“(”。
所以我们对左括号“\(”加上正向后行断言“(?<=\()”,即内容的左侧必须是左括号但不显示它,这样就相当于去掉了左括号。
至此左括号与右括号就都不显示了。
我们通过下面的一个例子理解(?<!) 负向后行断言
比如我们要提取的数字有一个特点,就是数字的前面必须不能为A。
可以先提取数字:
=REGEXP(A2,"\d+")
\d+:表示任意的多个数字。
此时所有数字都被提取到了。
我们对左侧的A加上负向后行断言:
=REGEXP(A2,"(?<!A)\d+")
(?<!):负向后行断言,左侧不得出现指定模式
(?<!A)\d+:表示任意数字的左侧必须不能是A。数字1的前面是A,所以不符合,只有数字26的左侧符合不是A。
我们通过下面的一个例子理解(?!) 负向先行断言
比如我们要提取的数字有一个特点,就是数字的后面必须不能为A。
可以先提取数字:
=REGEXP(A2,"\d+")
\d+:表示任意的多个数字。
此时所有数字都被提取到了。
我们对右侧的A加上负向先行断言 :
=REGEXP(A2,"\d+(?!A)")
(?!):负向先行断言,右侧不得出现指定模式
\d+(?!A):表示任意数字的右侧必须不能是A。数字6的右面是A,所以不符合,只有数字12的右侧符合不是A。