zoukankan      html  css  js  c++  java
  • JS对象类型RegExp

    本篇文章主要介绍RegExp对象以及RegExp的实例的属性和方法,如果对于正则的基础语法还不是很清楚,可以参考下RegExp基础语法这篇文章

    实例属性

    RegExp实例都包含下面5个属性

    global: 布尔值,表示是否设置了g标志
    ignoreCase: 布尔值,表示是否设置了i标志
    multiline:布尔值,表示是否设置了m标志
    lastIndex:整数,表示开始搜索下一个匹配项的字符位置,从0开始
    source:正则表达式的字符串表示(按照字面量形式而非传入构造函数中的字符串模式返回)
    
    var p1 = /[bc]at/i;
    
    console.log(p1.global);//false
    console.log(p1.ignoreCase);//true    
    console.log(p1.multiline);//false
    console.log(p1.lastIndex);//0
    console.log(p1.source);//'[bc]at'
    

    如果设置了RegExp的全局模式'g',使用exec()或test()函数时,正则表达式的匹配就会从lastIndex的位置开始,并且在每次匹配成功之后重新设定lastIndex。这样,就可以在字符串中重复迭代,依次寻找各个匹配结果。但是,如果需要对不同字符串调用同一个RegExp的exec()或test()方法,这个变量可能会带来意料之外的匹配结果,所以在更换字符串时,要显式地将RegExp的lastIndex置为0

    var p1 = /\w/g;
    var s1 = 'ab';
    var s2 = 'ba';
    
    // 默认值
    console.log(p1.lastIndex); // 0
    
    p1.exec(s1);
    console.log(p1.lastIndex); // 1
    // s2从位置1开始匹配
    p1.exec(s2);
    console.log(p1.lastIndex); // 2
    

    构造函数属性

    RegExp构造函数属性会基于所执行的最近一次正则表达式操作而变化。有两种方式访问它们,即长属性名和短属性名,短属性名大都不是有效的ECMAScript标识符,所以必须通过方括号语法来访问它们

    长属性名           短属性名         说明
    input             $_                最近一次要匹配的字符串
    lastMatch         $&                最近一次的匹配项
    lastParen         $+                最近一次匹配的捕获组
    leftContext       $`                input字符串中lastMatch之前的文本
    rightContext      $'                input字符串中lastMatch之后的文本
    multiline         $*                布尔值,表示是否所有表达式都使用多行模式
    
    var text = 'this has been a short summer';
    var pattern = /(.)hort/g;
    if(pattern.test(text)){
        console.log(RegExp.input);//'this has been a short summer'
        console.log(RegExp.leftContext);//'this has been a '
        console.log(RegExp.rightContext);//' summer'
        console.log(RegExp.lastMatch);//'short'
        console.log(RegExp.lastParen);//'s'
        console.log(RegExp.multiline);//false
    
        console.log(RegExp['$_']);//'this has been a short summer'
        console.log(RegExp['$`']);//'this has been a '
        console.log(RegExp["$'"]);//' summer'
        console.log(RegExp['$&']);//'short'
        console.log(RegExp['$+']);//'s'
        console.log(RegExp['$*']);//false        
    }
    

    JavaScript有9个用于存储捕获组的构造函数属性,RegExp.$1、RegExp.$2、RegExp.$3……到RegExp.$9分别用于存储第一、第二……第九个匹配的捕获组。在调用exec()或test()方法时,这些属性会被自动填充

    比如,要匹配诸如2018-08-12这样的日期字符串

    /(\d{4})-(\d{2})-(\d{2})/.test('2018-08-12');
    console.log(RegExp.$1);//'2018'
    console.log(RegExp.$2);//'08'
    console.log(RegExp.$3);//'12'
    console.log(RegExp.$4);//''
    
    // 理论上,应该保存整个表达式匹配文本的RegExp.$0并不存在,值为undefined
    console.log(RegExp.$0);//undefined
    

    实例方法

    实例方法分为两类:一类是是继承而来的,包括toString()、toLocalString()、valueOf();一类是非继承的,包括test()和exec()

    继承方法

    RegExp对象继承了Object对象的通用方法toString()、toLocaleString()、valueOf()这三个方法

    toString():toString()方法返回正则表达式的字面量

    toLocaleString():toLocaleString()方法返回正则表达式的字面量

    valueOf():valueOf()方法返回返回正则表达式对象本身

    var pattern = new RegExp('[bc]at','gi');
    console.log(pattern.toString()); // '/[bc]at/gi'
    console.log(pattern.toLocaleString()); // '/[bc]at/gi'
    console.log(pattern.valueOf()); // /[bc]at/gi
    
    var pattern = /[bc]at/gi;
    console.log(pattern.toString()); // '/[bc]at/gi'
    console.log(pattern.toLocaleString()); // '[bc]at/gi'
    console.log(pattern.valueOf()); // /[bc]at/gi
    

    注意: 不论以哪种方式创建正则表达式,这三个方法都只返回其字面量形式

    exec()

    exec()方法专门为捕获组而设计,接受一个参数,表示要应用模式的字符串,返回包含匹配项信息的数组,在没有匹配项的情况下返回null

    匹配项数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串(如果模式中没有捕获组,则该数组只包含第一项)

    返回的数组包含两个额外的属性:index和input。index表示匹配项在字符串的位置,input表示应用正则表达式的字符串

    console.log(/(\d{4})-(\d{2})-(\d{2})/.exec('date 2018-08-12 10:30'));
    

    对于exec()方法,在不设置全局标志的情况下,在同一个字符串上多次调用exec(),将始终返回第一个匹配项的信息;而在设置全局标志的情况下,每次调用exec()都会在字符串中继续查找新匹配项。

    无全局标志示例

    var text = 'cat,bat,sat,fat';
    var pattern = /.at/;
    var m1 = pattern.exec(text);
    console.log(m1);    
    var m2 = pattern.exec(text);
    console.log(m2);
    

    有全局标志示例

    var text = 'cat,bat,sat,fat';
    var pattern = /.at/g;
    var m1 = pattern.exec(text);
    console.log(m1);    
    var m2 = pattern.exec(text);
    console.log(m2);
    

    扩展: 用exec()方法找出所有匹配项的位置和值

    var str = 'a1b2c3d4';
    var p = /[a-z]/g;
    var i = [], v = [], ret;
    while((ret = p.exec(str)) != null) {
      i.push(ret.index);
      v.push(ret[0]);
    }
    console.log(i, v); // [0, 2, 4, 6] ["a", "b", "c", "d"]
    

    test()

    test()方法用来测试正则表达式能否在字符串中找到匹配文本,接收一个字符串参数,匹配时返回true,否则返回false

    /\d/.test('1'); // true
    /\d/.test('a'); // false
    

    同样地,在调用test()方法时,会造成RegExp对象的lastIndex属性的变化。如果指定了全局模式,每次执行test()方法时,都会从字符串中的lastIndex偏移值开始尝试匹配,所以用同一个RegExp多次验证不同字符串,必须在每次调用之后,将lastIndex值置为0

    var pattern = /^\d{4}-\d{2}-\d{2}$/g;
    console.log(pattern.test('2018-08-12'));//true
    console.log(pattern.test('2018-08-12'));//false
    
    //正确的做法应该是在验证不同字符串前,先将lastIndex重置为0
    var pattern = /^\d{4}-\d{2}-\d{2}$/g;
    console.log(pattern.test('2018-08-12'));//true
    pattern.lastIndex = 0;
    console.log(pattern.test('2018-08-12'));//true
    
    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    C++文件读写详解(ofstream,ifstream,fstream)
    C++ char*,const char*,string,int 的相互转换
    Properties --- C++读配置信息的类
    值得推荐的C/C++框架和库
    leetcode 264: Ugly Number II
    几种Tab的实现方法
    HBase数据存储格式
    粗略。。Java项目设计模式之笔记----studying
    开放的平台、向上的文化——揭秘万达电商(4)
    RecyclerView
  • 原文地址:https://www.cnblogs.com/yesyes/p/15352724.html
Copyright © 2011-2022 走看看