惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
人人都是产品经理
人人都是产品经理
Engineering at Meta
Engineering at Meta
小众软件
小众软件
I
InfoQ
有赞技术团队
有赞技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Martin Fowler
Martin Fowler
月光博客
月光博客
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
V
Visual Studio Blog
博客园 - 叶小钗
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
GbyAI
GbyAI
P
Proofpoint News Feed
Apple Machine Learning Research
Apple Machine Learning Research

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
JS replaceAll 和 matchAll 使用指南不指北 « 张鑫旭-鑫空间...
张鑫旭,zhangxinxu · 2022-08-21 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=10499 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

封面图-纸飞机

一、先说下 replaceAll

replaceAll 这个 API 是最近一两年新出来的 API,可能某些浏览器,例如360极速版之类的并不支持(虽然使用的是 Chromium 内核,但版本太老),以及部分老旧的 Android 设备。

这个 API 我可是喜欢的很,可以轻松解决以前一些比较头疼的字符串处理需求。

比方说搜索关键字的高亮匹配。

就像下图所示这样,搜索字母 x,结果本人名字有两个字的拼音与之相符:

名字高亮

咦?不对不对,不是这个,应该是叠词匹配,也就是假设我的名字叫做:张鑫鑫,则搜索“鑫”的时候应该两个字都高亮。

上面的图我P下,稍等……

字符匹配

如果只是匹配一个字符,直接使用 replace 就可以了,简单到爆炸。

name = name.replace('鑫', '<mark>鑫</mark>');

可要是希望所有的“鑫”字都高亮,replace 就从老六变成二五仔了,只能使用正则进行替换了,由于用户输入框输入的内容是动态的,所以,只能使用 new RegExp() 实现。

// 实际开发,new RegExp() 中  
name = name.replace(new RegExp('鑫', 'g'), '<mark>鑫</mark>');

然而使用RegExp使用有两大缺点:

1. 难,新人表示臣妾记不住啊,每次使用都要看看语法是什么,哪像replace方法这么通俗易懂。
2. 烦,动态输入内容不可控,要是有特殊字符,还需要转义,不然作为 RegExp 的参数会有问题。

好在现在有了 replaceAll 方法,就可以轻松替换所有匹配的字符串了,简单到爆炸+1。

name = name.replaceAll('鑫', '<mark>鑫</mark>');

二、replaceAll的语法和细节

语法

replaceAll 语法和 replace 一样,均支持字符串替换或者正则替换:

replaceAll(pattern, replacement)

但是具体细节上会有一些区别。

细节

首先,replaceAll 中的正则表达式中一定要有’g’这个全局标识符,否则会报错。

例如下面的 JS 执行就会报错:

'hello world'.replaceAll(/\s/, '');
// 会报错

Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument

报错提示

其次,和replace方法一样,replaceAll也是连空字符串也能匹配替换的,例如:

'张鑫旭'.replaceAll('', '_')

返回的结果是:’_张_鑫_旭_’

如下截图所示:

空字符串替换

因此,在实现搜索高亮匹配的时候,如果是空字符串,需要不执行匹配操作,否则会插入很多预期之外的 <mark> 元素。

兼容性

IE浏览器并不支持,其他浏览器均已支持,如下图所示:

replaceAll兼容性

三、再说下 matchAll

matchAll 方法也是最近三年才支持的,支持时间比 replaceAll 方法要早个一年半载。

match 方法相比,matchAll 的返回值不仅包括匹配的内容,还包括匹配的分组(也就是正则表达式中括号括起来的部分)。

下面通过一个例子展示下两者的区别。

let str = 'author\'s name is zxx';
const reg = /\s+([a-z]+)/g;

console.log(str.match(reg));
console.log(str.matchAll(reg));

两者的返回值分别是:

match 方法返回:[' name', ' is', ' zxx']
matchAll 返回:RegExpStringIterator,转为数组后值为:

[Array(2), Array(2), Array(2)]
0: (2) [' name', 'name', index: 8, input: "author's name is zxx", groups: undefined]
1: (2) [' is', 'is', index: 13, input: "author's name is zxx", groups: undefined]
2: (2) [' zxx', 'zxx', index: 16, input: "author's name is zxx", groups: undefined]
length: 3

Chrome console面板中执行后的结果示意为:

matchAll 截图示意

可以看到,match 方法忽略的分组,直接返回匹配的数组内容,而 matchAll 返回的迭代器中的数组项中就包含了分组捕获的内容,从作用上来看,有些类似于 regexp.exec() 方法(数组项的返回值也是一样的)。

不过细节上还是有区别,matchAll 的正则是一锤子买卖,reg.lastIndex 是固定不变的,没法像 regexp.exec() 一样通过修改 lastIndex 使正则表达式前进或后退。

语法和细节

语法如下:

matchAll(regexp)

其中,regexp 表示正则表达式,其中,必须带有 ‘g’ 全局标识符,否则会报错,这一点和 replaceAll 方法一致。

当没有任何匹配的时候,match 方法返回的是 nullmatchAll 则返回的是可迭代迭代器,转数组后是空数组,和匹配时候的数据类型一致,因此,在实操上,JS 执行出错概率要更小(对于新人而言)。

兼容性

直接看图,绿意盎然:

matchAll 绿意盎然

四、结语啊哈

由于 matchAll 只能和正则表达式打交道,因此,matchAll 在 JS 代码中的传播和使用率一定是小于 replaceAll 的,因为正则表达式是很多开发人员的软肋,一知半解,能避则避。

这显然不是长久之计,正则表达式一定要认真学习,反复实践,要达到完全可以自己手写复杂正则表达式的境界才可以。

有句话是怎么说来着,凡事需要对字符串处理的地方,都可以使用正则表达式,如果正则表达式不行,那就再写一个正则表达式。

好了,就说这么多吧。

最近有个紧急项目,加班多,同时在赶《CSS选择器世界》的稿子,以及周末钓鱼比较多,所以文章更新滞后了,这一周会补上。

噢啦,啊哈,记得点赞哦!

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=10499

(本篇完)