这篇文章发布于 2022年08月21日,星期日,15:27,归类于 JS API。 阅读 9366 次, 今日 6 次 没有评论
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浏览器并不支持,其他浏览器均已支持,如下图所示:
三、再说下 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面板中执行后的结果示意为:
可以看到,match
方法忽略的分组,直接返回匹配的数组内容,而 matchAll
返回的迭代器中的数组项中就包含了分组捕获的内容,从作用上来看,有些类似于 regexp.exec()
方法(数组项的返回值也是一样的)。
不过细节上还是有区别,matchAll
的正则是一锤子买卖,reg.lastIndex 是固定不变的,没法像 regexp.exec()
一样通过修改 lastIndex
使正则表达式前进或后退。
语法和细节
语法如下:
matchAll(regexp)
其中,regexp
表示正则表达式,其中,必须带有 ‘g’ 全局标识符,否则会报错,这一点和 replaceAll
方法一致。
当没有任何匹配的时候,match
方法返回的是 null
,matchAll
则返回的是可迭代迭代器,转数组后是空数组,和匹配时候的数据类型一致,因此,在实操上,JS 执行出错概率要更小(对于新人而言)。
兼容性
直接看图,绿意盎然:
四、结语啊哈
由于 matchAll
只能和正则表达式打交道,因此,matchAll
在 JS 代码中的传播和使用率一定是小于 replaceAll
的,因为正则表达式是很多开发人员的软肋,一知半解,能避则避。
这显然不是长久之计,正则表达式一定要认真学习,反复实践,要达到完全可以自己手写复杂正则表达式的境界才可以。
有句话是怎么说来着,凡事需要对字符串处理的地方,都可以使用正则表达式,如果正则表达式不行,那就再写一个正则表达式。
好了,就说这么多吧。
最近有个紧急项目,加班多,同时在赶《CSS选择器世界》的稿子,以及周末钓鱼比较多,所以文章更新滞后了,这一周会补上。
噢啦,啊哈,记得点赞哦!
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=10499
(本篇完)
- 深入 JS new Function 语法 (0.742)
- JavaScript实现http地址自动检测并添加URL链接 (0.470)
- JS 标签模板(Tagged templates)什么时候使用? (0.364)
- 翻编-JavaScript有关的10个怪癖和秘密 (0.258)
- 粉丝群第27期JS基础小测答疑文字版 (0.258)
- JS字符串补全方法padStart()和padEnd()简介 (0.212)
- jQuery之replace字符串替换实现不同尺寸图片切换 (0.152)
- JS一般般的网页重构可以使用Node.js做些什么 (0.152)
- Ajax Upload多文件上传插件翻译及中文演示 (0.106)
- 文本框邮箱地址自动提示jQuery插件 (0.106)
- 我是如何理解"Another JavaScript quiz"中的题目 (RANDOM - 0.106)