ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[分享] WPS JS自定义正则表达式函数提取复杂字符串文本

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-4-14 19:28 | 显示全部楼层 |阅读模式
本帖最后由 仙女配凡人 于 2023-4-15 18:39 编辑

    不管是 MS Office 还是 WPS Excel 目前都没有正则表达式功能,对于复杂的文本嵌套多层公式非常麻烦,好在WPS支持 JavaScript 语言自定义函数,我们只需要封装好函数,就可以在单元格用公式使用正则表达式了,本篇介绍在 WPS 中用 JS 封装自定义函数,等 MS Office 啥时候支持 JavaScript 语言再出一篇

    通过WPS宏编辑器自定义RegExpMatch、RegExpReplace两个函数,把代码保存为xlam文件添加到加载项(xlam文件可理解为没有工作表的工作簿),就能自动跟随Excel启动,并且在所有工作簿都能使用。
  1. //单元格引用正则表达式方法 =RegExpMatch(字符串(必选), 表达式(必选), 索引(可选), 连接符(可选))
  2. function RegExpMatch(text, pattern, index = 0, joint) {
  3.   if (typeof(text) == 'function') text = text.Value2;
  4.   if (typeof(pattern) == 'function') pattern = pattern.Value2;
  5.   if (typeof(index) == 'function') index = index.Value2;
  6.   if (typeof(joint) == 'function') joint = joint.Value2;

  7.   let i = pattern.lastIndexOf('/') //返回/字符最后的索引
  8.     , e = pattern.slice(1, i)      //获取匹配模式
  9.     , m = pattern.slice(i + 1)     //获取修饰符
  10.     , re = new RegExp(e, m);       //创建正则

  11.   if (re.test(text)) {
  12.     let mch = text.match(re);
  13.     if (joint) return mch.join(joint);
  14.     if (index >= mch.length) return '超出索引范围[0, ' + (mch.length - 1) + ']';
  15.     return mch[index]
  16.    
  17.   } else {
  18.     return '无匹配'
  19.   }
  20. }

  21. //单元格引用函数方法 =RegExpReplace(字符串(必选), 表达式(必选), 替换的文本(必选))
  22. function RegExpReplace(text, pattern, replaced) {
  23.   if (typeof(text) == 'function') text = text.Value2;
  24.   if (typeof(pattern) == 'function') pattern = pattern.Value2;
  25.   if (typeof(replaced) == 'function') replaced = replaced.Value2;

  26.   let i = pattern.lastIndexOf('/')
  27.     , e = pattern.slice(1, i)
  28.     , m = pattern.slice(i + 1)
  29.     , re = RegExp(e, m);

  30.   return text.replace(re, replaced)

  31. }
复制代码




函数说明
一、RegExpMatch函数,提取匹配到的字符
RegExpMatch(字符串(必选), 匹配模式(必选), 索引(可选), 连接字符(可选))
参数名称 可选/必选 数据类型 说明
字符串 必选 文本 要处理的文本,可引用单元格
匹配模式 必选 文本 跟 JavaScript 正则表达式语法一样:/匹配模式/修饰符,例如全局匹配类型数字:/\d+/g
全局匹配并忽略大小写title:/title/gi
其中修饰符g表示全局、i忽略大小写、m多行模式、s包括换行符
索引 可选 数字 返回匹配到的第几项,注意索引都是从0开始
连接字符 可选 文本 指定字符,拼接所有匹配到的项


匹配最后一项3-4位数字带大写字母W的数据:
数据在A列,B列单元格输入公式:=RegExpMatch(A2,"/\d{3,4}W(?=[^W]+$)/")
QQ截图20230415023313.png

匹配下面的JSON字符串,把所有匹配到的项用 | 字符拼接起来:
数据在A列,匹配模式在B列,则在C列输入公式:=RegExpMatch(A1,A2,0,"|")
{"code": 0,"medias":[{"title":"那年廿八,还是单身,站着如喽啰","index":2},{"title":"首尔街头美女遍地走体验驻韩美军的快乐","index":9},{"title":"春日和我约会吧!5套日常LOOK分享","index":17},{"title":"「su_ll」白桃乌龙茶艺妆,你女朋友没那么小气吧","index":25}]} /(?<=title":").*?(?=",)/g =RegExpMatch(A1,A2,0,"|")



二、RegExpReplace函数,替换匹配到的字符
RegExpReplace(字符串(必选), 匹配模式(必选), 替换的文本(必选))
例如在重命名工作表的时候,工作表名称开头与结尾不得是单引号,并且不得含有字符:: \ / ? * [ ]
数据在A列,将特殊字符全部替换为 - 则B列输入公式:=RegExpMatch(A1,"/^'|'$|[\\/?*\[\]]/g","-")
行号 工作表名称 输入公式 返回结果
1 95 [周一].xlsx =RegExpMatch(A1,"/^'|'$|[\\/?*\[\]]/g","-") 95 -周-一.xlsx
2 周*雨.xlsx =RegExpMatch(A2,"/^'|'$|[\\/?*\[\]]/g","-") 周-雨.xlsx
3 '=100/50.xlsx =RegExpMatch(A3,"/^'|'$|[\\/?*\[\]]/g","-") -=100-50.xlsx


评分

4

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-4-15 00:53 | 显示全部楼层
本帖最后由 仙女配凡人 于 2023-4-15 15:12 编辑

完整代码在这
  1. //单元格引用正则表达式方法 =RegExpMatch(字符串(必选), 表达式(必选), 索引(可选), 连接符(可选))
  2. function RegExpMatch(text, pattern, index = 0, joint) {
  3.   if (typeof(text) == 'function') text = text.Value2;
  4.   if (typeof(pattern) == 'function') pattern = pattern.Value2;
  5.   if (typeof(index) == 'function') index = index.Value2;
  6.   if (typeof(joint) == 'function') joint = joint.Value2;

  7.   let i = pattern.lastIndexOf('/') //返回/字符最后的索引
  8.     , e = pattern.slice(1, i)      //获取匹配模式
  9.     , m = pattern.slice(i + 1)     //获取修饰符
  10.     , re = new RegExp(e, m);       //创建正则

  11.   if (re.test(text)) {
  12.     let mch = text.match(re);
  13.     if (joint) return mch.join(joint);
  14.     if (index >= mch.length) return '超出索引范围[0, ' + (mch.length - 1) + ']';
  15.     return mch[index]
  16.    
  17.   } else {
  18.     return '无匹配'
  19.   }
  20. }

  21. //单元格引用函数方法 =RegExpReplace(字符串(必选), 表达式(必选), 替换的文本(必选))
  22. function RegExpReplace(text, pattern, replaced) {
  23.   if (typeof(text) == 'function') text = text.Value2;
  24.   if (typeof(pattern) == 'function') pattern = pattern.Value2;
  25.   if (typeof(replaced) == 'function') replaced = replaced.Value2;

  26.   let i = pattern.lastIndexOf('/')
  27.     , e = pattern.slice(1, i)
  28.     , m = pattern.slice(i + 1)
  29.     , re = RegExp(e, m);

  30.   return text.replace(re, replaced)

  31. }
复制代码


TA的精华主题

TA的得分主题

发表于 2023-4-18 15:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册

上次帮我写的代码能再优化一下吗?

已整理表格,求助分类汇总.zip

57.18 KB, 下载次数: 3

TA的精华主题

TA的得分主题

发表于 2023-4-18 15:22 | 显示全部楼层
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-4-27 16:34 , Processed in 0.032333 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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