js正则表达式

原文:http://www.cnblogs.com/xiaofu/articles/1613463.html

1.正则表达式

正则的exec方法和字符串的match方法,当没有全局标志g时,它们两的行为是一样的,有index,input,lastindex等属性!除了返回与表达式相匹配的文本外,所有匹配的子串也会返回!!
             1.1使用RegExp对象

                     例:

                     var match=”cat”;
                     var reCat=/cat/;
                     或 reCat=new RegExp(“cat”);
                     alert(reCat.test(match));//
                     RegExp的test方法测试字符串是否匹配这个模式。
                     var match=”a bat,a Cat,a fAt bat,a faT cat”;

                     var reAt=/at/;
                     var arrMatches=reAt.exec(match);

                     RegExp对象的exce方法返回一个数组,数组中的第一条目是第一个匹配;其他的是反向引用。
                     String对象数组有的match()方法,它会返回一个包含所有字符串中的所有匹配的数组。

                     var s=”a bat,a Cat,a fAt bat,a faT cat”;
                     var reAt=/at/gi;
                     或 reCat=new RegExp(“cat”,”gi”);
                     var arr=s.match(reAt);

                     String对象的Search()字符串方法返回在字符串中出现的一个匹配的位置。

                  Alert(s.search(reAt));

             1.2扩展的字符串方法

                     String对象的replace()和split()方法都可以传递正则表达式。
                     这里的replace()方法的第二个参数可以传递一个函数。这处函数可以接受一个参数,即匹配了的文本,并返回应当进行替换的文本

                     var tt=”The sky os red”;
                     var re=/red/;

                     var sText=tt.replace(re,function(sMatch){ return “blue”;});


                     sMatch这个参数就是用模式re匹配后的文本!!

       2.简单模式
              2.1元字符
                     正则表达式的元字符是正则表达式语法的一部分。

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

                     任何时候要在正则表达式中使用元字符都必须对它们进行转义用’\’。      

                     Var retest=/\?/;

                     或var retest=new RegExp(“\\?”);//必须用两个反斜杠,如果用的一个反斜杠,那么JS解释器会按照\n的方式翻译\?.

              2.2使用特殊字符

                     转义字符

              2.3字符类

                     就是把一些字符放入方括号中,然后正则表达式去匹配里面的各个字符。也即只能匹配方括号中的任意一个字符,不是同时匹配全部啊!!!

                    2.3.1.简单类
                            例:[adf]等
                     2.3.2.负向类
                            例:[^adf]等,告诉正则表达式不能匹配脱字符^后面跟着的字符。
                     2.3.3.范围类
                            例:[a-z] [A-Z] [0-9] [^b-z]等
                     2.3.4.组合类
                            例 [a-m1-4\n]注意各个内部类之间没有空格。
                     2.3.5.预定义类

                            代码             等同于                         匹配

                            .             [^\n\r]                          除了换行和回车之外的任意字符      

                            \d           [0-9]                                   数字

                            \D           [^0-9]                          非数字

                            \s            [\t\n\f\r\x0b]                 空白符

                            \S           [^\t\n\f\r\x0b]               非空白符

                            \w           [a-xA-Z_0-9]                单词字符 (有可能匹配汉字)看语言支持Unicode字段否

                            \W          [^a-xA-Z_0-9]                     非单词字符

              2.4量词

                     2.4.1.简单量词

                     代码                                          描述

                     ?                                                出现零次或一次

                     *                                               出现零次或多次(任意次)

                     +                                               出现一次或多次

                     {n}                                            刚好出现n次

                     {n,m}                                        至少出现n次,至多m次

                     {n,}                                           至少出现n次

              2.4.2.贪婪的、惰性的和支配性量词

                     贪婪性量词先看整个字符串是否匹配,如果没有匹配,它先去掉该字符串最后一个字符,并再次尝试。这个过程一直重复下去。

                     惰性量词先看字符中的第一个字符是否匹配,如果不匹配,就读入下一个量词,组成两个字符的字符串,再比匹配。这个过程一直重复下去,直到匹配或没有匹配。

                     支匹配性量词只尝试匹配整个字符串,如果整个字符串不能产生匹配,不做进一步尝试。

贪婪                            惰性                                   支配

?                                  ??                                       ?+

*                                 *?                                       *+

+                                 +?                                       ++

{n}                              {n}?                                          {n}+

{n,m}                          {n,m}?                                {n,m}+

{n,}                             {n,}?                                  {n,}+

例:

              Var sToMatch=”abbbaabbbaaabbb1234”;
              Var re1=/.*bbb/g;
              Var re2=/.*?bbb/g;

              Var re3=/.*+bbb/g;

              如果想获得的匹配是”abbb”,”aabbb”,”aaabbb”,这三个表达式中只有re2能匹配成功。

              2.4.3标志

                     字符                                   含义

                     i                                  执行不区分大小定的匹配

                     g                                 执行一个全局匹配,即找到所有匹配,而不是在找到第                                                        一个之后就停止

                     m                                多行模式,^匹配一行的开头和字符串的开头,$匹配一行的结尾或字符串的结尾

       2.5复杂模式

              2.5.1分组

                     分组是通过用括号包围一系列字符、字符类及量词来使用的。每次必须全部匹配括号中的所有字符。

                     例:

                            var reg1=/(dog)?/;//匹配0个或一个dog字符串序列

                            var reg2=/(dog)*/;//匹配0 个或多个dog字符串序列

                            var reg3=/(dog){2}/;//字符序列”dog”将在一行上连续出现两次!

              2.5.2反向引用

                     在表达式计算完后对分组的利用,即每个分组都被存储在一个特殊的地方以备使用。这些存储在分组中的特殊值,我们称之为反向引用。

                     反向引用是按照从左到右遇到的左括号字符的顺序进行创建和编号的。例如表达式(A?(b?(c?)))将产生编号1-3的三个反向引用。

                     (1)(A?(B?(c?)))

                     (2)(B?(c?))

                     (3)(c?)

                     首先,使用正则表达式对象的test() 、exec()方法或string对象的match() 、search()方法后,反向引用的值可以从RegExp构造函数中得到

              例:

                     var test=”#12345”;
                     var re=/#(\d+)/;
                     re.test(test);
                     alert(RegExp.$1);

                     使用这test方法后,所有的反向引用都被保存在RegExp构造函数,从RegExp.$1开始,如果还有第二个引用,就是RegExp.$2.

                     然后,还可以直接在定义分组的表达式中包含反向引用,这可以通过使用特殊转义序列\1 \2等实现。

                     var tt=”dogdog”;                 
                     var re=/(dog)\1/;
                     alert(re.test(tt));//outputs ‘true”

                     正则表达式re首先创建单词dog的组,然后又被特殊转义序列\1引用,使得这个表达式等同于/dogdog/。

                     最后,反向引用可以用在String对象的replace()方法中,这通过使用特殊字符序列$1、$2等实现。

                     var str=”1234 5678”;
                     var re=/(\d{4})(\d{4})/;
                     var new=str.replace(re,”$2 $1”);
                     alert(new);//outputs “5678 1234”;

              2.5.3.候选

                     例

                            var  strRed=”red”;
                            var  strBlue=”blue”;
                            var   re1=/(red | blue)/;

                            把一个管道符”|” 放在两个单独的模式之间,如上所示。当对这个模式进行测试时,只要有一个被匹配就返回true,因为它相当于一个or模式,即任何一个匹配就可以。

              2.5.4非捕获性分组

                     前面的产生反向引用的分组,我们称之为捕获性分组。如果分组不想产生反向引用,那么只要在括号的后面加一个问号和一个紧跟的冒号.

                     var t=”#3142134”;
                     var re=/#(?:\d+)/;
                     re.test(t);
                     alert(RegExp.$1);//outputs “”;

              2.5.5前瞻

                     它告诉正则表达式运算器向前看一些字符而不移动其位置。

                     正向前瞻检查的是接下来出现的是不是某个特定字符集。而负向前瞻则是检查接下来的不应该出现的特定字符集。

                     创建正向前瞻要将模式放在(?=和)之间,注意,这不是分组,虽然它也用到了括号。事实上,分组是不会考虑前瞻的存在的。

                     var str1=”bedroom”;
                     var str2=”bedding”;
                     var re=/(bed(?=room))/;
                     alert(re.test(str1));//outputs “true”
                     alert(RegExp.$1));//outputs “bed”;
                     alert(re.test(str2))//ouputs “false”;

                     创建负向前瞻要将模式放在(?和)之间,

                     var str1=”bedroom”;
                     var str2=”bedding”;
                     var re=/(bed(?!room))/;
                     alert(re.test(str1));//outputs “false”
                     alert(RegExp.$1));//outputs “bed”;
                     alert(re.test(str2))//ouputs “true”;

              2.5.6边界

                     指定了模式的位置。$,^可以改变匹配的方向,或者说是改变贪婪和惰性量词的默认行为。看下面例子

                     边界                     描述

                     ^                          行开头

                     $                          行结尾

                     \b                         单词的边界,就是位于\w和\W之间的位置,或位于字符\w                                           和字符串的开头或结尾之间的位置。

                     \B                         非单词边界

                     例:

                            var str=”Important word is ths last one”;
                            var re=/(w+)\.$/;
                            re.test(str);

                     这个例子查找的一行结束之前出的跟着一个句号的一个或多个单词字符。这个例子它改变了那个贪婪性量词的方向,它先匹配整个串,然后去掉头的一个字符,继续匹配下去。

                     var str=”Important word is ths last one”;
                     var re=/\(.+?)\b/;
                     re.test(str);
                     alert(RegExp.$1);//outputs “important”

                     这里用惰性量词来制定在单词边界之前可以出现任何字符,且可出现一个或多次。

                     注意行的开始和行的结束,通常由^和$表示的位置,对应也也认为是单词的边界。

              2.5.7多行模式

                     要指定多行模式,只要在正则表达式后面添加一个m选项。这会让$边界匹配换行符(\n)以及字符串真正的结尾。

                     多行模式同样会改变^边界的行为,这时它会匹配换行符之后的位置。

                     var str=”first second\nthird fourth\nfifth sixth”;
                   var re=/(\w+)$/gm;
                 var new=str.match(re);//outputs “second”,”fourth”,”sixth”

       2.6理解RegExp对象

              2.6.1实例属性

                     有用的lastIndex属性,它可告诉你正则表达式在某个字符串中停止之前,查找了多远(即下次匹配将会从哪个字符位置开始)。这个属性只对exec和test方法才会填入(废话,RegExp对象只有这两个方法)。必须要有全局标志(g)才行。

                     var str=”bbq is short”;
                     var re=/b/g;
                     re.exec(str);
                     alert(re.lastIndex);//outputs “1”;下次从第二个b开始,位置1
                     re.exec(str);
                     alert(re.lastIndex);//outputs “2”

              2.6.2RegExp对象的两个方法

                     test()方法

                            检测一个字符串是否含有一个模式。

                      exec()方法

                            (1) 在调用非全局(没加g标志)的RegExp对象的exec()方法来检索字符串string,从中得到与表达式regexp相匹配的文本。如果exec()找到了匹配的文本,它就会返回一个结果数组。否则,返回一个null。这个返回的第0个元素就是与表达式相匹配的文本。第1个元素是与regexp的第一个子表达式(分组表达式)相匹配的文本。第2个元素以此类推。还有一个length属性,除了length属性和数组元素外,exec()方法还返回两个属性,index属性声明的是匹配文本的第一个字符的位置,input属性指定的就是string。在调用非全局(没加g标志)的RegExp对象的exec()方法时,返回的数组与调用方法String.match()方法相同。

                            在调用全局的RegExp对象的exec()方法时,exec()的行为不同。它每次匹配是从regexp的属性lastIndex指定的字符处开始检索字符串string(相当于它是有记忆的,执行一次后,下次该从哪执行是记录下来的,而没有加全局标志的每次都string头开始匹配查找)。当它找到了与表达式相匹配的文本时,在匹配后,它将把regexp的lastIndex属性设置为匹配完文本后的下一个字符的位置。这样可以反复调用exec()方法来匹配所有匹配文本。当再也找不到匹配文本时,返回null,自动把属性设置为0。当然它的第1个元素及以后的元素仍然存放的是子表达示的文本。这在match()方法中是没有的。

                            简单的来说,exec()方法的全局检索和非全局检索区别在于:全局检索会多出一个lastIndex索引来指示下一次开始匹配字符的位置。而且可以多次调用exec()方法来匹配所有匹配文本。

                            (2) 如果 regexp 没有标志 g,那么 match() 方法就只能在 stringObject 中执行一次匹配。如果没有找到任何匹配的文本, match() 将返回 null。否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息。该数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本。除了这些常规的数组元素之外,返回的数组还含有两个对象属性。 index 属性声明的是匹配文本的起始字符在 stringObject 中的位置,input 属性声明的是对 stringObject 的引用。

                            如果 regexp 具有标志 g,则 match() 方法将执行全局检索,找到 stringObject 中的所有匹配子字符串。若没有找到任何匹配的子串,则返回 null。如果找到了一个或多个匹配子串,则返回一个数组。不过全局匹配返回的数组的内容与前者大不相同,它的数组元素中存放的是 stringObject 中所有的匹配子串(也就是说返回的数组中不是存放的正则表达式的子达式的匹配文本而是与个表达式匹配的文本,可能有多个),而且也没有 index 属性或 input 属性。

注意,无论regexp是否全局模式,exec()会将完事的细节添加到返回的数组中。这是exec()方法与match()方法不同的地方。

                            例如:

                            var pattern=/\bJava\w*\b/g;
                            var text="JavaScript is more fun than Java or JavaBeans";
                            while((result=pattern.exec(text))!=null)
                                   {
                                   alert("Matched '"+result[0]+"' at position "+result.index+" next seatch begins at position "+ pattern.lastIndex);
                                   }//必须循环才能找出所有匹配文本。
                            //
                            “1 plus 2 equals 3”.match(/\d+/g) // returns [“1”,”2”,”3”]返回的子串
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值