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

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

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

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

关闭

常用JavaScript正则表达式整理

在表单验证中,正则表达式书写起来特别繁琐,本文整理了15个常用的JavaScript正则表达式,其中包括用户名、密码强度、整数、数字、电子邮件地址(Email)、手机号码、身份证号、URL地址、 IPv4地址

JavaScript判断字符串包含中文字符的方法总结

JS中判断一个字符串是否包含汉字,下面就介绍2中常用的实现方法:用正则表达式判断、用 Unicode 字符范围判断。

javascript正则表达式:匹配所有html标签

这个正则表达式也是收集于网络,但是我可以看懂,首先,html标签肯定是以<符号开始的,以>符号结束(不管是不是自闭合),只是中间有点纠结,可能有字符,数字,引号,换行符——但是,却万万没有>,因为有它的话html标签就结束了

最新JS正则大全(常用)

12小时制时间(hh:mm:ss);base64格式;数字/货币金额(支持负数、千分位分隔符);银行卡号(16或19位);中文姓名;新能源车牌号

17 个案例带你 5 分钟搞定 Linux 正则表达式

正则表达式是一种字符模式,用于在查找过程中匹配制定的字符。元字符通常在Linux中分为两类:Shell元字符,由Linux Shell进行解析;正则表达式元字符,由vi/grep/sed/awk等文本处理工具进行解析;

JS常用正则表达&RegExp对象

本来想细致整理一下正则表达式和RegExp对象的,但是发现网上完善的教程一抓一大把,于是这篇文章只会记录一些常常用到的正则表达式以及稍做分析。

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

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

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

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

一次记住js的6个正则方法

来记忆一些常用特殊字符,这个是正则本身的范畴了,是不是总觉得记不住?其实我也记不住,每次都是去搜索和online验证来完成一些任务。我也困恼过,其实最后还是因为自己写的少吧,唯手熟尔。。。

JavaScript 正则表达式

正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索和文本替换。

点击更多...

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