Javascript每日一题

2021-07-28 11:55 Javascript每日一题

单选

const arr = ['apple', 'book', 'coffee']const doubleWords = []// 此正则匹配所有拥有双字母单词const reg = /(\w)\1/gfor (let word of arr) {  if (reg.test(word)) {    doubleWords.push(word)  }}console.log(doubleWords) // ?


  1. ['apple', 'book', 'coffee']
  2. ['apple', 'coffee']


图片


解析


由于 RegExp (/(\w)\1/g) 设置了 g 标志,所以它的 lastIndex 属性会在每次成功匹配后被修改。所以,每次执行 reg.test(word) 的时候,它的 lastIndex 指定的位置开始下一次搜索。为了更清楚了解其中的原理,我们先看一个简单的例子:

图片


由上可知,每次执行 exec 时,返回的 lastIndex 都会发生变化,当匹配不了时将返回 null,并且 lastIndex 值变为 0。
所以,当 reg.test(word) 匹配完 apple 中的 pp 后,lastIndex将变为 3,因此,在搜索 book 时就会跳过其中的 oo 而返回 null。因此选择


答案: B


解决方案


如果想要实现  答案 A 的效果,代码应该怎么改?


方案一:

删除 g 标志,在这个例子中 g 并不是必须的。
// 省略代码...const reg = /(\w)\1/// 省略代码...

方案二:

将 RegExp 字面量移到循环体内。
// 省略代码...if (/(\w)\1/g.test(word)) {  // 省略代码...}// 省略代码...

方案三:

每次调用 reg.test 之前把 lastIndex 重置为0。
// 省略代码...reg.lastIndex = 0// 省略代码...

方案四:最佳方案

使用 ES2020 matchAll() 方法,因为 matchAll 并不会去修改 lastIndex。
// 省略代码...if (word.matchAll(reg)) {   // 省略代码...}// 省略代码...


思考


猜猜下面方法会运行出什么?请 谨慎 运行下面代码

const str = 'abcabcabc'let match, positions = []while ((match = /a/g.exec(str)) !== null) {  positions.push(match.index)}



End

本文章转载自公众号:javascript_daily

首页 - Javascript 相关的更多文章: