关闭

循环下的正则匹配?说说正则中的lastIndex

时间: 2018-09-12阅读: 991标签: 正则

最近在使用正则匹配的时候,我遇到一个非常有意思的现象,代码如下所示:

const reg = /\.jpg/g;
const arr = [
    'test1.jpg',
    'test2.jpg',
    'test3.jpg',
    'test4.jpg',
    'test5.jpg',
];
arr.map(item => console.log(reg.test(item)));

这段代码很好理解:它的规则就是判断字符串中是否含有.jpg,然后再循环地和数组中的字符串进行匹配,打印出结果。

很显然这非常之简单嘛,输出的结果当然是全为true啦~


然而,图样图森破,它的结果是这样的:

代码的执行结果非常神奇:它并没有全部打印true,而是交替打印true和false值,这到底是为什么?
为了查清楚到底是怎么回事,我开始上网搜索相关资料,经过一番搜索后,发现正则并没有我们想象的那么简单...


what's going on?

首先正则有一个属性叫lastIndex,它表示正则下一次匹配时的起始位置。一般情况下我们是使用不到它的,但在正则中包含全局标志g时,正则的test和exec方法就会使用到它,具体规则如下:

  • 初始状态下lastIndex的值为0
  • 若成功匹配,lastIndex的值就被更新成被匹配字符串后面的第一个字符的index,或者可理解为被匹配字符串的最后一个字符index + 1
  • 若匹配失败,lastIndex则被重置为0。
  • 如果我们继续使用原先的正则进行下一轮匹配,它则会从字符串lastIndex的位置开始进行

为验证这个结论,我特意做了两个实验:

第一个就是直接将正则的lastIndex打印出来:

const reg = /\.jpg/g;
const arr = [
    'test1.jpg',
    'test2.jpg',
    'test3.jpg',
    'test4.jpg',
    'test5.jpg',
];
arr.map(item => console.log(reg.test(item), reg.lastIndex));



第二个就对数组中的字符串稍作修改:

const reg = /\.jpg/g;
const arr = [
    'test1.jpg',
    'longTest4.jpg',
    'test3.jpg',
    'longTest4.jpg',
    'test5.jpg',
];
arr.map(item => console.log(reg.test(item), reg.lastIndex));


通过两组实验的对比观察,发现确实如此:

在第一个实验中,由于数组中字符串的长度都是一致的,成功匹配后lastIndex的值直接更新为9,下次匹配的时候直接从第10个字符开始(很明显根本就没第10个字符嘛),因此匹配失败,lastIndex重置为0。以此类推,最终以9、0、9的形式交替打印。

而第二个实验由于我们增加了部分字符串的长度,因此对于第2、4个字符串而言,即使从第9个字符开始匹配,依然能匹配到后边的.jpg,故lastIndex继续更新到13


通过这次小小的实验,我们发现使用正则的时候还是要多加小心,对于test和exec方法,最好还是不要随意加上全局标志g。

来源:https://segmentfault.com/a/1190000016361529


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/1072

关闭

JS校验身份证号的合法性

前端表单中有身份证号的校验,下边是用JS来校验身份证号的合法性。中国居民身份证号码编码规则、中国居民身份证校验码算法、JS校验身份证合法性。

javascript较全常用的表达正则验证,js中采用test()方法

正则表达式是一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。本文整理了JS较全且实用正则表达式。

前端的正则表达式:基本概念

正则表达式(regex)是定义搜索模式的字符序列。由于对程序员的日常工作非常有用,所以在 JavaScript 中也支持它。在这个系列文章中,我会向你展示其工作方式以及其实际用途

正则表达式后行断言 • 探索 ES2018 和 ES2019

先后行断言(Lookaround Assertion)是正则表达式中的一个构造,明确了当前位置的前后字符序列,但没有其他副作用。当前 JavaScript 唯一支持的 Lookaround Assertion 是 先行断言,其匹配当前位置接下来的字符序列

JavaScript正则表达式常用技巧

正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript 中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、matchAll、replace、search 和 split 方法

javascript 正则表达式之分组与前瞻匹配详解

本文主要讲解javascript 的正则表达式中的分组匹配与前瞻匹配的,需要对正则的有基本认识。分组匹配:捕获性分组匹配、非捕获性分组匹配。前瞻匹配:正向前瞻匹配: (?=表达式) 后面一定要匹配有什么、反向前瞻匹配: (?!表达式) 后面一定不能要有什么

JS正则:密码强度8位以上,且包含大小写字母、数字、半角英文符号

本正则规则:包含数字,包含大写字母,包含小写字母,包含英文标点符号,至少8位以上,以上条件必须全部满足,则可以通过验证

用正则匹配富文本中的文本,并替换其内容

其次需要利用字符串的 replace 函数,当第一个入参是正则的时候,第二个参数可以用函数的形式来接受正则的匹配结果,且这个函数的返回值会用来替换被正则匹配到的字符串

ES6正则的扩展

参数为字符串, 那么第二个参数表示正则表达式的修饰符,如下:字符串对象共有4个方法,可以使用正则表达式: match()、 replace()、search() 和 split()。

从vue模板解析学习正则表达式

最近在看vue的模板解析成render这一块,顺便补一下正则的知识。attribute这段正则很长,他的主要作用是匹配标签里的指令,可以分几个分组来解读

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!