zoukankan      html  css  js  c++  java
  • 循环下正则匹配的问题

    最近在使用正则的时候,遇到一个奇怪的现象,代码如下

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

    代码非常简单,就是循环匹配校验图片后缀名,看一下运行结果

    结果并没有达到预期的结果,结果不是全是true, 而是交替打印的true 和false

    为什么会这样?

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

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

    下面我们来打印一下 lastIndex

    明白的lastIndex的规则,解决办法就很明显了

    1. 在正则中去掉全局标志 g

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

    2. 就是每次匹配之后都将 lastIndex 置为 0

    const reg = /.jpg/g;
    var arr = ['test1.jpg', 'test2.jpg', 'test3.jpg', 'test4.jpg'];
    
    arr.map(item => {
        console.log(reg.test(item));
        reg.lastIndex = 0;
        return item;
    });

    其实每一个 RegExp 对象都包含5个属性, source、gloable、ignoreCase、multiline、lastIndex。

    source:是一个只读的字符串,包含正则表达式的文本。

    global:是一个只读的布尔值,看这个正则表达式是否带有修饰符g。

    ignoreCase:是一个只读的布尔值,看这个正则表达式是否带有修饰符 i。

    multiline:是一个只读的布尔值,看这个正则表达式是否带有修饰符m。

    lastIndex:是一个可读/写的整数,如果匹配模式中带有g修饰符,这个属性存储在整个字符串中下一次检索的开始位置,这个属性会被exec( ) 和 test( ) 方法用到。

  • 相关阅读:
    Hibernate逆向工程
    使用Hibernate连接Oracle 无法识别生成的SQL问题
    法线的变换矩阵
    搭建Struts2开发环境
    留存: struts2+jquery+json集成
    一些WebGL的资源
    9个WebGL的演示
    WPF动画制作简单的按钮动画
    C# /windowForm/WPF/SilverLight里面操作Word帮助类提供给大家
    高斯投影正反算的代码
  • 原文地址:https://www.cnblogs.com/shenjp/p/9640439.html
Copyright © 2011-2022 走看看