③WPS新增的REGEXP函数,刚琢磨出的新颖用法

龙逸凡
龙逸凡

创作者俱乐部成员

今天是劳动节,不劳动有点说不过去,so,咱们今天继续更新。

写啥呢?

还是写REGEXP函数吧。REGEXP函数是最新版本的WPS才新增的。

这个函数好用,很好用,非常好用,真的很好用,好用到龙逸凡写了二篇文章还不过瘾,还要写第三篇

今天这篇我们来扩展一下,来看看它的另类用法。

第二参数为数组时会怎样?

将REGEXP函数的第二参数用常量数组看看会怎样:

=REGEXP(A1,{"[^一-龟]+","[一-龟]+"})

如果不理解什么是常量数组,请看这篇文章扫盲:

在第一篇文章中介绍过,

用=REGEXP(A1,"[^一-龟]+"})提取英文,

用=REGEXP(A1,{"[一-龟]+"})提取汉字。

详见下面链接的第4部分:

但当第二参数使用常量数组时,它只给出了每种情况的第一个值。

所以,可利用这个特点,来限定只提取第一个值:

=REGEXP(A1,{"[一-龟]+"})

我们继续深入。

如果第二参数是单元格区域会怎么样呢?

包含式反向查找(根据全称查简称)

工作中有时候需要根据长的文本来查短的。比如下图中凭证摘要中含有各品牌的车型。现在需要将车型提取出来。

以前我们是LOOKUP的经典套路公式来提取,

公式:

=IFNA(LOOKUP(9^9,FIND($C$3:$C$12,$F3),C$3:C$12),"")

这公式比较复杂,我们用REGEXP函数来提取试试,第二参数填入多个车型列表:

=REGEXP(F3,$C$3:$C$12,0)

可以看到,只有一个正确的结果,其他为#N/A

我们用TOCOL来过滤掉错误值,只留下正确的值:

=TOCOL(REGEXP(F3,$C$3:$C$12,0),2)

然后将公式下拉填充即可。

继续扩展,将摘要中购买的多个蔬菜和肉类名称提取出来合并:

=TEXTJOIN("、",1,TOCOL(REGEXP(B2,$F$2:$F$10),2))

根据不连续简称查全称

我们平时使用的很多简称,都是不连续的,比如“重庆大学”简称为“重大”,无法利用VLOOKUP函数的通配模式来查找。

这种情况的查找,其经典公式是这样的:

=INDEX($A$2:$A$9,MATCH(0,MMULT(-ISERR(FIND(MID(D2,COLUMN(A:Z),1),$A$2:$A$9)),$B$1:$B$26+1),))

公式很长、很复杂,如果用REGEXP函数就要简化一点,

公式:

=TOCOL(MAP($A$2:$A$9,LAMBDA(x,REGEXP(x,".*"&REGEXP(D2,"(.)",2,"\1.*")))),2)

解释:

要理解这公式首先要理解用REGEXP提取每一个字符(拆分):

然后再用REGEXP的替换模式来插入。

具体用法见最里面的REGEXP函数:

=REGEXP(D2,"(.)",2,"\1.*")

它是在每一个字之间插入“.*”,详细解释:

正则表达式"(.)"

这是一个捕获组,它匹配任何单个字符(. 表示任何字符,但只匹配一次)。捕获组 (...) 用于记住匹配的字符,以便稍后在替换字符串中使用。

  1. 第三参数为2,为替换模式

替换模式"\1.*"

\1:这是一个反向引用,它引用了第一个捕获组(在这种情况下,就是前面提到的单个字符)中匹配的文本。

"\1.*" 在第一个捕获组后面插入“.*”

再在这个REGEXP函数的计算结果的前面,添加一个".*",将拼接结果做为最外围的REGEXP函数的第二参数的正则表达式。

由于REGEXP函数的第一参数不支持数组。所以得用MAP+LAMBDA函数,将A2:A9单元格区域的单元格,逐个传递给REGEXP的第一参数。

然后用TOCOL过滤掉计算结果中的错误值。

给银行卡每四位添加一空格

从后往前每4位添加一空格的公式:

=REGEXP(A45,"(?=(?:\d{4})+$)",2," ")

正则表达式解释:

  1. (?=...):这是一个正向先行断言的语法。它告诉正则表达式引擎,我们需要匹配一个位置,该位置后面紧跟着括号内的模式,但光标(即匹配位置)不会移动到括号内的模式之后。

  1. (?:...):这是一个非捕获组。它用于对表达式进行分组,但不捕获匹配的文本,即匹配结果中不会包含这部分匹配的文本。

  1. \d{4}:匹配四位数字。\d 表示数字字符,{4} 表示恰好四次。

  1. +:表示匹配前面的元素(在这个情况下是四位数字)一次或多次。

  1. $:表示字符串的结尾。

从前往后每4位添加一空格的公式

=REGEXP(A45,"(\d{4})(?=\d)",2,"\1 ")

正则表达式解释:

  1. (\d{4}):这是一个捕获组。

  • \d 表示任意一个数字字符,等同于 [0-9]

  • {4} 表示前面的元素(在这里是数字字符 \d)重复四次。因此,\d{4} 匹配任意一个四位数。

  1. (?=\d):这是一个正向先行断言。

  • ?= 是正向先行断言的语法,它指定了一种条件,即在不消耗任何字符的情况下,检查其后面的字符是否符合指定的模式。

  • \d 再次表示任意一个数字字符。

给字符串中的数字添加千位分隔符

如果是数值,我们可以用TEXT函数来格式化,添加千位分隔符

公式:

=TEXT(B6,"#,##0.00元")

如果是文本中的数字,就不能使用TEXT函数了,可以用REGEXP函数来添加千位分隔符,公式:

=REGEXP(B2,"(?<=\d)(?=(?:\d{3})+($|[^\d年]))",2,",")

正则表达式解释:

  1. (?<=\d):这是一个后向断言,它用于匹配一个位置,该位置前面有一个数字(\d),但这个数字不会被包括在匹配结果中。

  1. (?=...):这是一个正向断言,用于匹配一个位置,该位置后面跟随有括号内的模式,但这个模式不会被包括在匹配结果中。

  1. (?:\d{3})+:这是一个非捕获组,用于匹配一个或多个连续的三位数。(?:...) 表示这是一个非捕获组,而 \d{3} 表示恰好三个数字字符。

  1. ($|[^\d年]):这是一个选择结构,用于匹配字符串的结尾($)或者一个非数字且非汉字“年”的字符([^\d年])。

  • $ 表示字符串的结尾。

  • [^\d年] 是一个字符集,匹配任何不是数字(\d)和汉字“年”()的字符。

统计个数

公式:

=SUM(--REGEXP(C3,$A$3:$A$19,1))

公式解释:

REGEXP函数的第3参数为1时,是判断模式,符合条件的为true、不符合的为false。然后在REGEXP函数前添加两个负号,负负得正,将逻辑值转化为1和为,然后用SUM求和。

看了上面的内容,是不是觉得REGEXP函数很神奇。

你还发现了哪些神奇的用法,欢迎留言

重庆
浏览 2407
16
15
分享
15 +1
13
16 +1
全部评论 13
 
0000
老师好,请问抓取到的结果中,怎么只取最后一条/最大值
· 广东省
回复
龙逸凡
龙逸凡

创作者俱乐部成员

=TAKE(你的公式,,-1)
· 重庆
回复
 
zha7090
zha7090

创作者俱乐部成员

请教:在A3单元格录入公式: =REGEXP(A1,"[一-龟]+") 可以正确执行,结果见下面的左图。 但是如果加上大括号后,在A5单元格录入带大括号的公式: =REGEXP(A1,{"[一-龟]+"}) 运行后,没有提示错误,单元格也没有东西(见下面的右图)。 谢谢!
· 广东省
回复
龙逸凡
龙逸凡

创作者俱乐部成员

我测试了一下,跟你的结果是一样的。应该是WPS将Regexp函数升级后(第三参数新增了”提取全部“),将此特性去掉了。解决方案:外面套一个INDEX或Take函数来取第一个提取结果
· 重庆
回复
 
鹿秋夏
REGEXP公式要怎么样才可以返回捕获组里面的内容呀~
· 广东省
回复
龙逸凡
龙逸凡

创作者俱乐部成员

文章中有相应示例
· 重庆
回复
 
zha7090
zha7090

创作者俱乐部成员

点赞,收藏
· 广东省
回复
 
伊卡黑石
REGEXP,我刚下载最新版本为啥没有这个函数。
· 吉林省
回复
龙逸凡
龙逸凡

创作者俱乐部成员

要下载16894版
· 重庆
回复
 
gong121
学习下
· 江西省
回复
 
马成功老师
马成功老师

创作者俱乐部成员

真是及时雨。顾不上吃饭了,恶补大神的知识中。
· 北京
回复
 
Boyuan
非常好,学习中, 有示例文件就更好了.
· 河南省
回复