JavaScript学习——RegExp类型

ECMAScript通过RegExp(Regular Expression)类型来支持正则表达式。

   var expression= / pattern / flags ;

pattern(模式)部分可以是任何正则表单时。每个正则表达式都可带有一个或多个flags(标志)。

g(global全局模式)
应用于所有字符串,而非发现第一个匹配项停止
i(case-insensitive)
确定匹配项时忽略模式与字符串的大小写
m(multiline) 在到达一行文本末尾时还会继续查找下一行是否存在与模式匹配的项

举例:

 1 /*
 2  *  匹配字符串中所有“at”的实例
 3  */
 4  var pattern1=/at/g;
 5 /*
 6  *  匹配第一个“cat”或“bat”的实例,不区分大小写
 7  */
 8  var patern2=/[cb]at/i;
 9 /*
10  *  匹配所有以“at”结尾的3个字符的组合,不区分大小写
11  */
12  var pattern3=/.at/gi;
13  /*
14   *  匹配所有“.at”,不区分大小写
15   */
16  var pattern4=/\.at/gi;

正则表达式常用来检索替换符合某个模式的文本,Regular Expreesion通常简写为RegExp RegEx RE具体概念(http://zh.wikipedia.org/wiki/正则表达式)

正则表达式学习:http://www.greenend.org.uk/rjk/tech/regexp.html(各种语言或工具软件不同的正则表达式文法规定);

                     http://deerchao.net/tutorials/regex/regex.htm(正则表达式30min入门);

                     http://mengzhuo.org/regex/(一个在线正则表达式验证器)。

让我们看看这下面这个例子:

1 /*
2  *  匹配第一个"bat"或“cat”,不区分大小写
3  */
4  var pattern1=/[bc]at/i;
5 /*
6  *   和pattern1相同,只不过是用来了构造函数创建
7  */
8  var pattern2=new RegExp("[bc]at","i");

这两个正则表达式是完全等价的,但是值得注意的是传递给构造函数RegExp的两个参数都是字符串类型,所以,在某些情况下,会对字符串参数进行双重转义。即对元字符进行转义,转义后的元字符再进行转义。

牢记元字符(metacharacters):( [ { \ ^ $ | ? * + . } ] ) 14个非常重要的元字符

举例:

想要匹配字符串 字面量模式 等价的字符串
"bat"或"cat" /[bc]at/ "[bc]at"
".at" /\.at/ "\\.at"
"\hello\world\" \\hello\\world\\ "\\\\hello\\\\world\\\\"

使用正则表达式字面量和使用RegExp构造函数创建的正则表达式还有一点也是有区别的,那就是在ECMAScript3中,使用正则表达式字面量始终会事会使用同一个RegExp实例,而RegExp构造函数会重新创建一个新的实例。但在ECMAScript5中明确规定,适应正则表达式字面量必须和直接调用RegExp构造函数一样,每次都创建一个新的RegExp实例。IE9+,Firefox4+,和chrome都据此做出了修改。

请看下面的例子(运行标准为ECMAScript3):

 1     var re=null,
 2     i;
 3     for (i = 0; i < 10; i++) {
 4         re=/cat/g
 5         document.write(re.test("catastrophe"));
 6     }
 7     for (i = 0; i < 10; i++) {
 8         re  = new RegExp("cat", "g");
 9         document.write(re.test("catastrophe"));
10     };

第一个for循环当re第二次调用时,会是从索引3进行查找。所以以后的都会显示false.而在chrome中运行则没有问题,在做这个例子的时候,因为一个小的问题,导致浪费了很多的时间,本来很快就可以解决的,是我打了一个中文输入法的括弧。

RegExp的属性:这些东西没有多大的用处,因为这些全部都包括在模式声明中了:

global,ignoreCase,lastIndex,multiline,source(RegExp并不是以字符串返回的,而是通过专一的字面量)

 1 var pattern1=/\[bc\]at/i;
 2     document.write(pattern1.global);      //false
 3     document.write(pattern1.ignoreCase);  //true
 4     document.write(pattern1.lastIndex);   //0
 5     document.write(pattern1.multiline);   //false
 6     document.write(pattern1.source);      //"\[bc\]at"
 7     var pattern2= new RegExp("\\[bc\\]at","i");
 8 
 9     document.write(pattern2.global);      //false
10     document.write(pattern2.ignoreCase);  //true
11     document.write(pattern2.lastIndex);   //0
12     document.write(pattern2.multiline);   //false
13     document.write(pattern2.source);      //"\[bc\]at"

RegExp对象方法:

RegExp对象的主要方法是exec(),该方法是专门为捕获组而设计的。exec()接受一个参数,就是要应用模式的文本,然后返回包含第一个匹配项信息的数组。或者在没有匹配项的情况下返回null.返回的数组有额外的两个属性:index和input.其中index表示匹配项在文本中的位置,而input表示应用正则表达式的字符串。

1     var text="mom and dad and baby";
2     var pattern= /mom( and dad( and baby)?)?/gi;
3 
4     var matches= pattern.exec(text);       
5     document.write(matches.index+"<br/>"); //0
6     document.write(matches.input+"<br/>"); //mom and dad and baby
7     document.write(matches[0]+"<br/>");    //mom and dad and babt
8     document.write(matches[1]+"<br/>");    //and dad and baby
9     document.write(matches[2]+"<br/>");    //and baby

当文本传入exec()方法后,发现了第一个匹配项,所以index属性为0,因为匹配项和文本相同。第二个匹配项是and dad and baby ,第三个匹配项是and baby.在调用非全局exec()方法时,,返回的数组与调用方法 String.match() 返回的数组是相同的。但是,在调用全局exec()全局方法时,exec的方法稍显复杂,他会在RegExp对象的lastIndex属性指定的字符处开始检索字符串,在exec()方法找到匹配文本后,以匹配文本的最后一个字符的下一个位置设置为RegExp的lastIndex属性,这就是说当用exec()方法遍历整个文本后,找不到匹配项后,它会返回null,并且把lastIndex设置为0。

看下面的例子:

1     var pattern=/.at/g;
2     var matches = pattern.exec(text);
3     document.write(matches.index);     //0
4     document.write(matches[0]);        //sat
5     document.write(pattern.lastIndex); //3

在IE中,JavaScript实现在lastIndex会出现差异,即使在非全局模式下,lastIndex属性也会发现变化。

正则表达式的第二个方法是test(),它接受应给字符串参数,在模式与该参数匹配的情况下返回true,反之返回false。

RegExp对象继承的toLocaleString()和toString()方法都会返回正则表达式的字面量,与创建正则表达式的方式无关。而是用valueOf()方法则返回正则表达式本身。

例如:

1     var pattern = new RegExp("\\[bc\\]at", "gi");
2     document.write(pattern.toString());      //"/\[bc\]at/gi"
3     document.write(pattern.toLocaleString());//"/\[bc\]at/gi"
4     document.write(pattern.valueOf());       //"/\[bc\]at/gi"

RegExp构造函数的属性:有些浏览器并不支持某些属性,比如Opera和IE

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

请看下面的例子:

 1     var text="this has been a short summer";
 2     var pattern=/(.)hort/g;
 3 
 4     if(pattern.test(text)){
 5         alert(RegExp.input);        //this has been a short summer
 6         alert(RegExp.leftContext);  //this has been a
 7         alert(RegExp.rightContext); //summer
 8         alert(RegExp.lastMatch);    //short
 9         alert(RegExp.lastParen);    //s
10         alert(RegExp.multiline);    //false
11     }

利用短属性名,因为这些短属性名不是有效的ECMAScript标识符,因此用方括号包括起来:

请看下面的例子,与上面的例子有相同的效果:

 1     var text="this has been a short summer";
 2     var pattern=/(.)hort/g;
 3 
 4     if(pattern.test(text)){
 5         alert(RegExp.$_);        //this has been a short summer
 6         alert(RegExp["$`"]);    //this has been a
 7         alert(RegExp["$'"]);    //summer
 8         alert(RegExp["$&"]);    //short
 9         alert(RegExp["$+"]);    //s
10         alert(RegExp["$*"]);    //false
11     }

除了上述的几个属性外,还有多达9个用于存储捕获组的构造函数属性。访问这些属性的方法是RegExp.$1,RegExp$2~RegExp.$9,分别用于存储第一,第二到第九个捕获组。

1     var text="this has been a short summer";
2     var pattern=/(..)or(.)/g;
3 
4     if(pattern.test(text)){
5         alert(RegExp.$1); //sh
6         alert(RegExp.$2); //t
7     }

这个正则表达式的意思是检索长度为5的字符串,其中倒数第3,2位为or,这个正则表达式有两个捕获组,圆括弧里面的,分别是(..)和(.)

关于捕获组的文章:http://blog.csdn.net/lxcnn/article/details/4146148

关于ECMAScript中正则表达式的局限性(下列是不支持的特性):请访问http://www.regular-expressions.info/javascript.html

匹配字符串开始和结尾的\A和\Z锚;

向后查找(lookbehind);

并集和交集类;

原子组(atomic grouping);

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

命名的捕获组;

s(single,单行)和x(free-spading,无间隔)匹配模式;

条件匹配;

正则表达式注释;

总而言之,ECMAScript正则表达式仍然是十分强大。

posted @ 2014-03-17 07:25  aidenliu  阅读(467)  评论(0编辑  收藏  举报