海拔5.4 RegExp类型

ECMAScript通过RegExp类型来支持正则表达式.

动下好像Perl的语法,就足以创建一个正则表达式.

var expression=/pattern/flags;

 

中的模式(pattern)部分好是其它简单的要复杂的正则表达式,可以涵盖字符类,限定符,分组,向前查找和反向引用.

每个正则表达式都不过含蓄一要多独标志(flags),用以标明正则表达式的行为.

正则表达式的相当模式支持下3只标志.

g:表示全局(global)模式,即模式将给使用为拥有字符串,而非以发现第一独相当配项时即停下;

i:表示不区分轻重缓急写(case-insensitive)模式,即当规定匹配项时忽略模式及字符串的轻重写;

m:表示多行(multiline)模式,即当抵一行文本末尾时还见面持续查找下一行中是不是有和模式匹配的项.

因而,一个正则表达式就是一个模式及上述3个标志的三结合体.不同组合产生不同的结果.

//匹配字符串的所有"at"的实例
    var pattern1=/at/g;

    //匹配第一个"bat"或"cat",不区分大小写
    var pattern2=/[bc]at/i;

    //匹配所有以"at"结尾的3个字符的组合,不区分大小写
    var pattern3=/.at/gi;

同其余语言中的正则表达式类似,模式面临采取的所有元字符都必须转义.

正则表达式的元字符包括:

( [ { \ ^ $ | ) ? * + . ] }

这些元字符在正则表达式中都出同等栽或多种多途,因此要想要配合配字符串的隐含的这些字符,就必对其进行转义.

//匹配第一个"bat"或"cat",不区分大小写
    var pattern1=/[bc]at/i;

    //匹配第一个"[bc]at/i",不区分大小写
    var pattern2=/\[bc\]at/i;

    //匹配所有以"at"结尾的3个字符的组合,不区分大小写
    var pattern3=/.at/gi;

    //匹配所有".at",不区分大小写
    var pattern4=/\.at/gi;

 

 

以上面例子中,pattern1匹配第一只”bat”或”cat”,不区分轻重缓急写.而思只要直接匹配”[bc]at”,就设针对有限独方括号进行转义.对于pattern3,句号表示在”at”之前的任意一个可以组成相当配项的字符.如果想匹配”.at”,就务须对时本身进行转义.

前面举的这些事例都是以字面量形式来定义之正则表达式.另一样种创建正则表达式的主意是用RegExg构造函数,它接受两只参数:一个假设配合的字符串模式,另一个凡可选的表明字符串.

可使字面量定义之任何表达式,都好下构造函数来定义,如下例子:

//匹配第一个"bat"或"cat",不区分大小写
    var pattern1=/[bc]at/i;

    //与pattern1相同,只不过是使用构造函数创建的
    var pattern2=new RegExp("[bc]at",i);

此的patttern1和pattern2是少单了等价格的正则表达式.

设留心的是,传递让RegExp构造函数的片单参数还是字符串(不可知将正则表达式字面量传递让RegExp构造函数).

是因为RegExp构造函数的模式参数是字符串,因此某些情况下如本着字符进行重新转义.

持有元字符都必须另行转义,那些都转义过的字符也是这样,例如\n(字符\在字符串中便为转义为\\,而当正则表达式字符串就见面成\\\\).

下表给出一些模式,左边为这些模式的字面量表示,右边为下RegExp构造函数定义相同模式时采取的字符串.

字面量模式 等价的字符串
/\[bc\]at/ “/\\[bc\\]at/”
/\.at/ “/\\.at/”
/name\/age/ “/name\\/age/”
/\d.\d{1,2}/ “/\\d.\\d{1,2}/”
/\w\\hello\\123/ “/\\w\\\\hello\\\\123/”

利用正则表达式字面量和动RegExp构造函数创建的正则表达式不一样.在ECMASscript
3饱受,正则表达式字面量始终会并享同一个RegExp实例,而下构造函数创建的各一个新RegExp实例都是一个新实例.看下例子

var re=null;
        i;

    for(var i=0;i<10;i++){
        re=/cat/g;
        re.test("catastrophe");
    }

    for(var i=0;i<10;i++){
        re=new RegExp("cat","g");
        re.test("catastrophe");
    }

以率先个巡回中,即使是循环体中指定的,但实则只为/cat/创建了一个RegExp实例.
由于实例属性不会见重置,所以当循环中再调用test()方法会失败.这是盖第一软调整用test()找到了”cat”,但第二浅调用是于目录为3的字符(上同糟匹配的末梢)开始之,所以即使招来不至其了.由于会测试到字符串末尾,所以下一致不良又调用test()就以打初步开始了.

老二个巡回利用RegExp构造函数在每次循环中开创正则表达式.因为老是迭代都见面创一个初的RegExp实例,所以每次调用test()都见面回true.

ECMAScipt
5明确规定,使用正则表达式字面量必须您一直调用RegExp构造函数一样,每次都创造新的RegExp实例.

IE+,FF4+和Chrome都用做出了修改.

5.4.1 RegExp实例属性

RegExp的每个实例都具有下列属性,通过这些性可以落有关模式的各种信息.

global:布尔值,表示是否设置了g标志.

ignoreCase:布尔值,表示是否设置了i标志.

lastIndex:整数,表示开搜下一个匹配项的字符位置,从0算起.

multiline:布尔值,表示是否设置了m标志.

source:正则表达式的字符串表示,按照字面量形式而未传入构造函数中之字符串模式返回.

通过这些性可以落知一个正则表达式的每方面的信息,但可不曾多大从而处,因为这些信都蕴含在模式声明中.例如

var pattern1=/\[bc\]at/i;

    console.log(pattern1.global);//false
    console.log(pattern1.ignoreCase);//true
    console.log(pattern1.multiline);//false
    console.log(pattern1.lastIndex);//0
    console.log(pattern1.source);// \[bc\]at

    var pattern2=new RegExp("\\[bc\\]at","i");
    console.log(pattern2.global);//false
    console.log(pattern2.ignoreCase);//true
    console.log(pattern2.multiline);//false
    console.log(pattern2.lastIndex);//0
    console.log(pattern2.source);// \[bc\]at

 

咱们注意到,尽管第一只模式使是许面量,第二独模式下了RegExp构造函数,但它的source属性是平等的.可见,source属性保存之是规范形式之字符串,即许面量形式所用的字符串.

5.4.2 RegExp实例方法

RegExp对象的重中之重方式是exec(),该法是特别为捕获组而规划之.

exec()接受一个参数,即要下模式的字符串,然后回到包含第一个门当户对项信息的数组;或者在没匹配项的事态下回到null.

回来的数组虽然是Array的实例,但含两单附加的性:index和input.

里面index表示相当配项在字符串的职位,而input表示用正则表达式的字符串.

以频繁组被,第一项是暨任何模式匹配的字符串,其他项是和模式遭遇之捕获组匹配的字符串(如果模式被无捕获组,则该数组只包含一宗).

对于exec()方法而言,即使在模式遭遇设置了全局标志(g),它每次也无非见面回一个匹项.

在不设置全局标志的场面下,在跟一个字符串上频繁调用exec()将一直返回第一只门当户对配项的信息.

假定以安装全局标志的情况下,每次调用exec()则还见面于字符串中延续搜寻新匹配项,如下面例子所示:

var text="cat,bat,sat,fat";
    var pattern1=/.at/;

    var matches=pattern1.exec(text);
    console.log(matches.index);//0
    console.log(matches[0]);//cat
    console.log(pattern1.lastIndex);//0

    matches=pattern1.exec(text);
    console.log(matches.index);//0
    console.log(matches[0]);//cat
    console.log(pattern1.lastIndex);//0

    var pattern2=/.at/g;

    var matches=pattern2.exec(text);
    console.log(matches.index);//0
    console.log(matches[0]);//cat
    console.log(pattern2.lastIndex);//3

    matches=pattern2.exec(text);
    console.log(matches.index);//4
    console.log(matches[0]);//bat
    console.log(pattern2.lastIndex);//7

 

 

于这事例中,第一独模式pattern1不是大局模式,因此老是调用exec()返回的还是首先单门当户对配项(“cat”).而第二只模式pattern2是全局模式,因此老是调用exec()都见面回去字符串中之生一个匹配项,直到搜索到字符串末尾为止.

另外,还要小心模式之lastIndex属性的别情况.
在全局匹配模式下,lastIndex的价值当历次调用exec()后还见面追加,而当非全局模式下则始终保不变.

留意:IE的JavaScript实现在lastIndex属性上有偏差,即使以非全局模式下,lastIndex属性每次也会见变化.

 

正则表达式的老二个点子是test(),它接受一个字符串参数.在模式与拖欠参数匹配的场面下返回true;否则,返回false.在只想明白对象字符串与某个模式是否匹配,但未需理解那文件内容之图景下,使用此法很方便.

故而,test()方法经常于用在if语句中,如下面例子所示:

var text="000-00-0000";
    var pattern=/\d{3}-\d{2}-\d{4}/;

    if(pattern.test(text)){
        console.log("The pattern was matched.");
    }

在这个例子中,用正则表达式来测试一个数字序列.如果输入文本和模式匹配,则显示平修消息.

这种用法经常出现在证明用户输入的景况下,因为咱们就想知道输入是无是有效,至于它们为何无效就无关紧要了.

RexExp实例继承的toLocaleString()和toString()方法都见面回来正则表达式的字面量,与创建正则表达式的方无关.

例如:

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

 

就是达到例被之模式是通过调用RegExp构造函数创建的,但toLocaleString()和toString()方法还是会如它是以字面量形式创建的等同显示其字符串表示.

在意:正则表达式的valueOf()方法返回正则表达式本身.

5.4.3 RegExp构造函数属性

RegExp构造函数包含部分性能(这些性在另外语言中吃当做是静态属性).这些性适用于作用域中之拥有正则表达式,并且根据所执的末段一破正则表达式操作而变化.

有关这些性之另外一个奇的远在,就是足以经过个别种植方式来走访它们.

转换句话说,这些性分别发生一个增长属性名和一个短属性名(Opera是殊,它不支持短属性名)

下表列有了RegExp构造函数的属性.

长属性名 短属性名 说明 
input $_ 最近一次要匹配的字符串.Opera未实现此属性
lastMatch $& 最近一次的匹配.Opera未实现此属性
lastParen $+ 最近一次匹配的捕获组.Opera未实现此属性
leftContext $` input字符串中lastMatch之前的文本
multiline $* 布尔值,表示是否所有表达式都使用多行模式.IE和Opera未实现此属性
rightContext $’ Input字符串中lastMatch之后的文本

应用这些性可以从exec()或test()执行的操作中领取出又现实的信息.

比方下面例子:

var text="this has been a short summer";
    var pattern=/(.)hort/g;

    //注意:Opera不支持input,lastMatch,lastParen和multiline属性
    //Internet Rxplorer不支持multiline属性
    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);//s
        console.log(RegExp.lastParen);//false
        console.log(RegExp.multiline);
    }

如上代码创建了一个模式,匹配任何一个字符后同hort,而且把第一独字符在了一个捕获组中.

 

RegExp构造函数的逐一属性返回了下列值:

input属性返回了原始字符串;

leftContext属性返回了单词short之前的字符串,而rightContext属性则赶回了short之后的字符串

lastMatch属性返回最近一模一样不善和整个正则表达式匹配的字符串,即short;

lastParen属性返回最近同样涂鸦匹配的捕获组,即例子中之s.

如前所述,例子使用的长属性名都足以用相应的短属性名来代替.只不过,由于这些短属性名大都不是卓有成效的ECMAScript标识符,因此要透过方括号语法来访问它们,如下所示.

var text="this has been a short summer";
    var pattern=/(.)hort/g;

    //注意:Opera不支持input,lastMatch,lastParen和multiline属性
    //Internet Rxplorer不支持multiline属性

    if(pattern.test(text)){
        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

 

 

除却上面介绍的几乎单特性外,还有多上9只用于存储捕获组的构造函数属性.访问这些性的语法是RegExp.$1,RegExp.$2……RegExp.$9,分别用于存储第一,第二…第九单相当的捕获组.在调用exec()和test()方法时,这些性会受活动填写充.

下一场就是得像下来利用她:

var test="this has a short summer";
    var pattern=/(..)or(.)/g;
    if(pattern.test(text)){
        console.log(RegExp.$1);//sh
        console.log(RegExp.$2);//t
    }

此间创办了一个分包两单捕获组的模式,并据此该模式测试了一个字符串.即使就test()方法就回去一个布尔值,但RegExp构造的函数的特性$1和$2也会见被匹配相应捕获组的字符串自填充.

5.4.4 模式的局限性

尽管ECMAScript中的正则表达式功能或比齐全的,但还缺乏某些语言(特别是Perl)所支持的高级正则表达式特性.

下列有了ECMAScript正则表达式不支持的性状:

相当配字符串开始与结尾的\A和\Z锚;(但支撑为插队入符号^和美元符号$来匹配字符串的开头同最终)

朝后找(lookbehind);(但一心支持上查找lookhead)

并集和交集类;

原子组(atomic grouping);

Unicode支持(单个字符除外,如\uFFFF);

命名的捕获组;(但支撑编号的捕获组)

s(single,单行)和x(free-spacing,无距离)匹配模式;

规则配合;

正则表达式注释;

 

不畏是这些限制,ECMAScript正则表达式仍然是异常强劲的,能够扶助咱得绝大多数模式匹配任务.