likes
comments
collection
share

使用正则/g引发的线上问题

作者站长头像
站长
· 阅读数 29

问题出现

某个周末正吃着火锅唱着歌,接到了领导的电话。

“快看一下投放到xx客户端的页面,怎么没有头(导航栏)了?”

立即打开app查看发现果真只剩秃秃的页面直通手机顶部,便立即放心手中的碗筷跑回了家查看问题。

解决问题

由于是周末,解决问题的过程是相当痛苦的。很艰难的联系上了客户端同学,发现客户端和我们的h5页面近期都没有做过改动,问题的矛头便指向了adapter(客户端和h5通信的解决方案,公司内部支撑组封装使用)。这里涉及到复杂的业务不过多赘述,但是支撑组有改动过代码的正则方法,将/g全局匹配去掉便解决了。

大胆猜想

既然证实是正则匹配/g搞的鬼,那么究竟是如何导致问题出现的呢?

在细读代码时发现,由于业务逻辑复杂,某个初始化方法调用了两次正则,这让我怀疑是两次调用的问题,但仍然是一头雾水,但是别无他法,硬着头皮敲下了下面这段代码,结果让我大吃一惊

接下来就翻译翻译什么是惊喜

小心论证

我们先来看一段代码

const name = "jielun de yanzi"
const reg = /jielun/g
reg.test(name)
// true 第一次是true
reg.test(name)
// false 第二次是false

这不就对上了嘛。全局匹配两次,最终匹配的结果就是false!

问题开始有趣了,立马打开mdn去重新学习RegExp

使用正则/g引发的线上问题

这就是tama的惊喜。

简单说来,/g在全局匹配的同时,还会有一个lastIndex参数去记录下标,如果匹配成功了,便会去记录成功位置的下标,再次匹配时,从下标记录的位置开始,所以第二次便会出现返回false的情况,返回false之后,lastIndex置为0,第三次会是true 第四次是false 。。如此循环下去

加深下理解

const str = "aaab"
const reg = /a/g
reg.test(str)
// true 第一次匹配第一个“a”,是true,lastIndex置为1
reg.test(str)
// true 第二次匹配第二个“a”,是true,lastIndex置为2
reg.test(str)
// true 第三次匹配第三个“a”,是true,lastIndex置为3
reg.test(str)
// false 第四次匹配index为3的“b”,结果便是false,lastIndex置为0
reg.test(str)
// true 第五次便是true了

总结&反思

  1. 大胆猜想,小心论证的思路在大佬那里学到后屡试不爽。
  2. js太深奥了,接触的越多 越觉得自己是废柴。
  3. 重要逻辑在使用不熟悉api时,要熟读文档。

参考资料

developer.mozilla.org/zh-CN/docs/…

blog.csdn.net/weixin_4255…

转载自:https://juejin.cn/post/7141290987275419684
评论
请登录