`
davice_li
  • 浏览: 93240 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Javascript正则表达式笔记(修正版)

阅读更多

^       The caret (^) tells the regular expression that the character must not match the characters to follow. 
        比如要匹配所有除了a或b的字符,字符类可以这么写[^ab] 
^      定位符规定匹配模式必须出现在目标字符串的开头 
        那是否说^ 在[ ] 里面 就 表示排除(负向类) , 在[ ] 前面 就表示要在开头 ? 
$      定位符规定匹配模式必须出现在目标对象的结尾 

-        范围类,如要匹配a到z的所有字母,字符类可以这么写[a-z] 

{n}   出现多少次 

/^[0-9]{7}$/    匹配的就是一个仅包含7个数字的字符串 


7.1 RegExp 对象可以有一个或两个参数. 
      var reCat = new RegExp ("cat")                      //这个表达式只会匹配字符串中出现的第一个"cat" 
      var reCat = new RegExp ("cat","g")               //匹配所有出现的"cat" 

     正则表达式字面量 
     var reCat = /cat/gi ;   注意字面量不需 要放在引号里 

     判断某个字符串是否匹配指定的模式 
     RegExp.test(str)                   如果给定的字符串匹配这个模式,返回true ,否则返回false .   reCat.test("cat")   //返回true 

     RegExp. exec(str)                 返回一个数组 ,数组中第一个元素是匹配字符串,其他是反向引用 . 如果没有找到匹配,返回null 
                                               返回的数组有一个index 属性,这个属性的值 是匹配字符串中第一个字符在原字符串中的下标 
                                              var toMarch6 = "1 3"; 
                       var regExp6 = /(\d+)\s*(\d+)/; 
                       var result = regExp6.exec(toMarch6); 
                       dwr(result);//1 3,1,3 
                                              dwr(RegExp.$1 +" "+RegExp.$2);//1 3 
                                              当正则表达式加上了参数g ,这个正则表达式会从正则表达式对象的lastIndex 属 性指定的位置开始查找,如果找到一个匹配, 
                                              会将lastIndex 属性设置为匹配字符串后面 一个位置的下标. 
                       var toMarch7 = "1 3 4 5"; 
                       var regExp7 = /(\d+)\s*(\d+)/g; 
                       var result7 
                       while((result7= regExp7.exec(toMarch7)) !=null){ 
                         dwr(result7);//分别为1 3,1,3 和 4 5,4,5 
                         dwr(regExp7.lastIndex);//分别为3和7 
                       } 
     String.match(reCat)            返回一个包含在字符串中的所有匹配 的数组 
                                               var toMatch = "a bat, a cat, a fAt baT, a faT cat"; 
                                               var reAt = /at/gi; //如果不加参数g,返回的数组只会包含一个匹配元素 
                                               var arrMatchs = toMatch.match(reAt); 
                                               返回一个数组["at","at","At","aT","aT","at"] 

     String.search(reCat)           与indexOf 类似,返回在字符串中出现的第一个 匹配的位置 ,全局匹配表达式g 在这里不起作 用    toMatch.search(reAt);//输出3 

     String.replace(matchStr, replaceStr)              
                                               用第二个参数替换 某个子串(第一个 参数)的所有匹配 . 第一个参数 既可以是匹配的字符串 ,也可以是用于匹配的一个正则表达式 , 
                                               返回是替换后的整个字符串 
                                               var sToChange = "The sky is red"; 
                                               var reRed = /red/; 
                                               sToChange.replace(reRed,"blue" );    //输出The sky is blue     

     String.split(reCat)              将字符串分割 成子串,作为数组 返回 
                                              var sColor = "red, blue, yellow"; 
                                              var reExp = /\,/; 
                                              var arrs = sColor.split(reExp);    //得到一个数组["red","blue","yellow" ]   注意逗号 在正则表达式有 
                                                                                                                        特殊含义 ,这边需要转义                

7.2  简单模式(元字符 ,字符类 ,量词 ) 
元字符      11个   ( ) [] {} \ ^ $ |  ? * + .       要匹配字符串中的元字符,需要转义   /\^/ 
注意var reMark = new RegExp("\\^"); 当正则表达式以非字面量的形式 表示时,所有的反斜杠"\" 都要用两个反斜杠"\\" 来替换. 
因为javascript字符串解析器会按照翻译\n 的 方式尝试翻译\?.为了保证不会出现这个问题,在元字符的前面加上两个反斜杠, 
我们称之为双重转义 .(不太懂这个解释,我的理解是\ 本身也是元字符,先要对它转义得到 "\" ,然后再用这个"\" 对接下来的元字符转义) 
预定义的特殊字符 
\t 
制表符 
\n 
换行符 
\r 
回车符 
\f 
换页符 
\a 
Alert 字符 
\e 
Escape 字符 
\cX 
与 X 相应 的控制字符 
\b 
回退字符 
\v 
垂直制表符 
\o 
空字符 



字符类   将一些字符放入方括号中 . 

1, 简单类      
   var toMatch = "a bat, a cat, a fAt baT, a faT cat"; 
   var reg = /[bcf]at/gi ; 
   var arrs = toMatch.match(reg);     返回的数组[“bat”, “Cat”, “fAt”, “baT”, “faT”, “cat”] 

2,负向类      可 以指定要排除的字符 ,^ 要在[ ] 里面 
   匹配除了 a 和b 以外的所有字符,那么这个字符类为[^ab] . 脱字符^ 告诉正则表达式字符不能匹配后面 跟着的字符 
   只想获得包含at但不能以b或c开头的字符, /[^bc]at/gi 

3, 范围类 
   [a-z] 匹配所有小写字母 
   结合负向类可以排除给定范围内的所有字符 , 例如要排除字符1~4,可以使用类[^1-4] 

4, 组合类 
   [a-z1-9\n] 

5, 预定义类 
代码                  等同于                            匹配 
.                      [^\n\r]                         除了换行回车意外的任意字符 
\d                   [0-9]                             数字 
\D                   [^0-9]                           非数字 
\s                   [ \t\n\r\x0B\f]         空白字符 
\S                   [^ \t\n\r\x0B\f]       非空白字符 
\w                   [a-zA-Z_0-9]               单词字符(所有字母,数字和下划线) 
\W                   [^a-zA-Z_0-9]             非单词字符 


6, 量词 
用于指定某个特定模式出现的次数 
?                     出现0次或1次 
*                     出现0次或多次(任意次) 
+                     出现1次或多次(至少出现一次) 
{n}                 一定出现n次 
{n,m}             至少出现n次但不超过m次 
{n,}               至少出现n次 

贪婪的,惰性的,支配性的量词 
贪婪量 词 先看整个字符串是否匹配,如果没有发现匹配,它去掉该字符串中最后一个字符,并再次尝试.重复这个过程直到发现匹配 或者字符串不剩任何字符. 
             结合 下面会见到的两个例子, 实际过程可能是这样的: 
             第一步按上面的描述执行, 如果字符串不剩任何字符还是没有找到一个匹配, 那么删除字符串的第一个字符, 重复第一步. 
惰性量词 先看字符串中第一个字符是否匹配.如果单独这个 字符还不够,就读入下一个字符,组成两个字符的字符串.如果还是没有发现匹配,惰性量词继续从 
             字符串中添加字符直到发现匹配或者整个字符串都检查过也没有匹配.与贪婪量词的工作方式正好相反. 
支配量词 只尝试匹配整个字符串.如果整个字符串不能产生匹配,不 做进一步尝试.(IE不支持,Mozilla把支配量词当做贪婪的) 

贪婪              惰性                  支配                 描述 
?                   ??                    ?+                    零次或一次出现 
*                   *?                     *+                    零次或多次出现 
+                   +?                     ++                    一次或多次出现 
{n}               {n}?                 {n}+               恰好n次出现 
{n,m}           {n,m}?             {n,m}+            至少n次之多m次出现 
{n,}             {n,}?               {n,}+              至少n次出现 


7.3 复杂模式 
1, 分组 
分组是通过一系 列括号包围一系列字符,字符类以及量词来使用的. 
/(dog){2}/g       匹配dogdog 
/{[bd]ad?}*/     匹配ba, da, bad, dad 等 
去掉开头结尾的空白字符 
String.prototype.trim = function(){ 
   //注意, 分组里面.*?一定要是惰性的,不然这 个分组会把最后的空白字符也匹配进去 
   var reExtraStr = /^\s+(.*?)\s+$/ ; 
   return this.replace(reExtraStr,"$1"); 


2, 反向引用 
在 表达式计算完成之后,每个分组都被存放在一个特殊的地方以备将来使用.这些存储在分组中的特殊值,我们称之为反向引用( backreference). 
反向引用是按照从左到右遇到的左括号字符的顺序进行创建和编号的. 

反向引用的几种不同使用方法: 
* 使用正则表达式对象的test(), exec()方法后,反向引用的值可以从RegExp对象的构造函数中获得 
var toMarch = "#12345"; 
var regExp = /#(\d*)/; 
regExp.exec(toMarch); 
dwr(RegExp.$1); 
* 还可以直接在定义分组的表达式中包含反向引用,这可以通过使用特 殊转义序列如 \1 , \2 等实现. 
var toMarch2 = "dogdog"; 
var regExp2 = /(dog)\1/; 
dwr(regExp2.test(toMarch2)); 
* 反向引用可以用在String对象的replace()方法中 
var toMarch3 = "123123123 3211231231"; 
var regExp3 = /(\d+)\s*(\d+)/; 
var sNew = toMarch3.replace(regExp3,"$2 $1 "); //注意replace不改变原来的字符串,而是返回一个替换后的新 字符串 
dwr(sNew); 

3, 候选 
用一个管道符(| ),它放在两个单独的模式之间. 
var toMarch4 = "dog"; 
var toMarch5 = "cat"; 
var regExp4 = /dog|cat/; 
dwr(regExp4.test(toMarch4));//true 
dwr(regExp4.test(toMarch5));//true 

OR模式的一种通常用法是从用户输入中删除不合适的单词. 
var userInput = "badWord1asdasdandBadWord2"; 
var toMarch6 = /badword1|badword2/gi; 
var newStr = userInput.replace(toMarch6, function(march){ 
    return march.replace(/./g,"*"); 
}); 
dwr(newStr); //********asdasdand******** 

string.replace(regexp, replacement) 
replacement 既 可以是一个替换的字符串,也可以是一个function 
如果是function的情况, 这个function会为每一个匹配执行一次,这 个function的返回值作为最终替换的字符串. 
传给function的第一个参数是 第一个匹配的字符串; 
第二个参数是匹配字符串在原始字符串中的位置; 
第三个参数是原始字符串本身. 

4, 非捕获性分组 
创建反向引用的分组称为捕获性分组, 非捕获性分组不会创建反向引用. 
在较长的正则表达式中存储反向引用会降低匹 配的速度. 
要创建非捕获性分组,只要在左括号后面紧跟一个问 号和冒号. 
var str = "#123456"; 
var regE = /#(?: 123456)/; 
regE.test(str); 
dwr(RegExp.$1); //"" 

//去除所有的HTML标签 
String.prototype.skipHTML = function(){ 
   var regExp = /<(?:.|\s)*?>/g ; 
   return this.replace(regExp,""); 


5, 前瞻 
表示当某个特定的字符分组出现在另一个字符串之前时才去捕获它. 
前瞻分正向前瞻 和负向前瞻 , 正向前瞻检查的是接下来出现的是不是某个特定的字符集. 而负向前瞻则是检查接下来的不应该出现的特定字符集. 
正向前瞻需要将模式放在(?= 和 ) 之间,注意这不是分组,虽然它也用到 括号. 负向前瞻需要将模式放在(!= 和 ) 之间. 
var toMarch1 = "bedroom"; 
var toMarch2 = "bedding"; 
var bedReg = /(bed(?=room))/; 
dwr(bedReg.test(toMarch1)); //true 
dwr(bedReg.exec(toMarch1)); //bed,bed 因此这个正则表达式返回的第一个匹配是bed,而不是bedroom,但是它只会去匹配后面跟着 room的bed,有点搞 
dwr(RegExp.$1); //bed 
dwr(bedReg.test(toMarch2)); //false 

6, 边界 
边界用于正则表达式中表示模式的位置. 
^                    行开头 
$                    行结尾 
\b                  单词的边界 
\B                  非单词的边界 

查找一个出现在行尾的单词: 
var toMarch3 = "Important word is the last one."; 
var regExp3 = /(\w+)\.$/ ; //这边结合上面对贪婪量词的解释,有点不明白为何能匹配one?. 
regExp3.test(toMarch3); 
dwr(RegExp.$1);//one 

查找一个出现在行首的单词: 
var toMarch4 = "Important word is the last one."; 
var regExp4 = /^(\w+)/ ; //或者var regExp4 = /^(.+?)\b/; 
regExp4.test(toMarch4); 
dwr(RegExp.$1); 

抽取出所有的单词 
var toMarch5 = "First Second Third Fourth Fifth Sixth"; 
var regExp5 = /\b(\S+?)\b/g ; //或者 /\b(\S+)\b/g 和 /(\w+)/g 
var sArr = toMarch5.match(regExp5); 
dwr(sArr);//First Second Third Fourth Fifth Sixth 
注意这边如果用/(\w+?)/g 是不行的,这样得到的是一个一个的字母F,i,r,s,t,S... 

========================================================================================== 
与上面疑问类似的一个问题 
例子代码,如下: 
str = "abbb1234abbbaabbbaaabbb1234"; 
re = /.*bbb/g; 
alert(str.match(re));    //结果为abbb1234abbbaabbbaaabbb 
re = /.*?bbb/g; 
alert(str.match(re));    //结果为abbb,1234abbb,aabbb,aaabbb 
re = /a*bbb/g; 
alert(str.match(re));    //结果为abbb,abbb,aabbb,aaabbb 
re = /a*?bbb/g; 
alert(str.match(re));    //结果为abbb,abbb,aabbb,aaabbb 

对于第一、第二和第四个打印结果容易理解: 
第一个str.match(re),贪婪量词先匹配整个字串,若不匹配去掉一个尾字 符,继续匹配; 
第二个str.match(re),惰性量词从第一个字符开始递加去匹配,直到匹配成功,清空字串,从下一个 字符继续匹配。 
第四个str.match(re),同第二个。 

但第三个就不知道如何解释,如果按照第一个的方式去理解: 
先 匹配整个字串,发现不匹配,去掉尾字符,继续匹配...到最后,结果应该是abbb; 
而其结果却为abbb,abbb,aabbb,aaabbb 

以下为论坛解释 
对于第三个正则,就是这样来执行的; 
首 先清楚了是用了简单量词(*),而我们知道了*是贪婪量词: 
贪婪量词执行过程。正好楼主所说的那样。“先匹配整体,若不匹配则去掉尾字 符继续匹配,直到成功或者结束” 
这样说应说只能得到第一被匹配的对象。 
javascript 中的match返回的是所有匹配。 
对于要返回所有匹配。 
它还有第二个步:就是匹配成功后, 从最近的一个匹配后的下一个字符开始重新贪婪模式匹配。 重新执行它的步骤; 
例: 
str = "abbb1234abbbaabbbaaabbb1234"; 
re = /a*bbb/g; 
alert(str.match(re)); 

它的执行过程: 
第一步:首先整个字符串("abbb1234abbbaabbbaaabbb1234")匹配,发现匹配不成 功, 
接着。删除最后一个字符("4"),成了("abbb1234abbbaabbbaaabbb123"),这样依次执行 下去; 
执行...最后, 发现("abbb")可以被匹配了..所以生成第一个匹配值。 

但在这个match方法中是返回所有匹配。所以.. 
第二步:从最近的一个匹配(这里就是第一次匹配了)后的下一个字符开始重新贪婪模式 匹配.得到字符串是 
("1234abbbaabbbaaabbb1234"),然后。就按第一步执行。。 

执行完第一步 后。 
然后就从最近一次(这里就是第二次匹配了) 

....后面的过程就是重复一二步了。。 

但第二步时若继续按正则/a*bbb/g 去匹配“1234abbbaabbbaaabbb1234” 的话,应该是匹配不到才对吧? 
--------------------------------------------------- 
怎么匹配不到呢。。 
正 则表达式执行的时候。首先得找到前导字符(a), a是一个普通字符。普通字符,搜索的顺序为从左到右。。 
所以搜索 “1234abbbaabbbaaabbb1234”字符串时, 
得先匹配出a字符来"abbbaabbbaaabbb1234”, 
而 解析器又发现了a后面是一个贪婪字符。就按贪婪模式去匹配(从右到左) 

注意: /a*bbb/g 用到了全局匹配, 以上分析的症结所在可能就是因为一个"g" 
========================================================================================== 

7, 多行模式 
一下代码中的正则表达式想要匹配行末的一个单词.它只会匹配最后的Sixth, 但实际上这个字符串包含两个换行符,因此, Second, Fourth也应该匹配出来,因此引入了多行模式 
var toMarch6 = "First Second\nThird Fourth\nFifth Sixth"; 
var regExp6 = /(\w+)$/g; 
var sArr6 = toMarch6.match(regExp6); 
dwr(sArr6); 
要 引入多行模式,需要在正则表达式后面添加m 选项, 这会让$边界匹配换行符(\n) 和字符串真正的结尾. 
var regExp6 = /(\w+)$/gm; 

判 断日期的正则表达式: 
function isValidDate(s){ 
    var reDate = /(?:[1-9]|0[1-9]|[12][0-9]|3[01])\/(?:[1-9]|0[1-9]|1[0-2])\/(?:19\d{2}|20\d{2})/; 
    return reDate.test(s); 




-- 
Best Regards 
RicoYu 
引用 收藏 

xulin_546430850 2010-03-27 
ricoyu 写道 
^       The caret (^) tells the regular expression that the character must not match the characters to follow. 
        比如要匹配所有除了a或b的字符,字符类可以这么写[^ab] 
^      定位符规定匹配模式必须出现在目标字符串的开头 
        那是否说^ 在[ ] 里面 就 表示排除(负向类) , 在[ ] 前面 就表示要在开头 ? 
$      定位符规定匹配模式必须出现在目标对象的结尾 

-        范围类,如要匹配a到z的所有字母,字符类可以这么写[a-z] 

{n}   出现多少次 

/^[0-9]{7}$/    匹配的就是一个仅包含7个数字的字符串 


7.1 RegExp 对象可以有一个或两个参数. 
      var reCat = new RegExp ("cat")                      //这个表达式只会匹配字符串中出现的第一个"cat" 
      var reCat = new RegExp ("cat","g")               //匹配所有出现的"cat" 

     正则表达式字面量 
     var reCat = /cat/gi ;   注意字面量不需 要放在引号里 

     判断某个字符串是否匹配指定的模式 
     RegExp.test(str)                   如果给定的字符串匹配这个模式,返回true ,否则返回false .   reCat.test("cat")   //返回true 

     RegExp. exec(str)                 返回一个数组 ,数组中第一个元素是匹配字符串,其他是反向引用 . 如果没有找到匹配,返回null 
                                               返回的数组有一个index 属性,这个属性的值 是匹配字符串中第一个字符在原字符串中的下标 
                                              var toMarch6 = "1 3"; 
                       var regExp6 = /(\d+)\s*(\d+)/; 
                       var result = regExp6.exec(toMarch6); 
                       dwr(result);//1 3,1,3 
                                              dwr(RegExp.$1 +" "+RegExp.$2);//1 3 
                                              当正则表达式加上了参数g ,这个正则表达式会从正则表达式对象的lastIndex 属 性指定的位置开始查找,如果找到一个匹配, 
                                              会将lastIndex 属性设置为匹配字符串后面 一个位置的下标. 
                       var toMarch7 = "1 3 4 5"; 
                       var regExp7 = /(\d+)\s*(\d+)/g; 
                       var result7 
                       while((result7= regExp7.exec(toMarch7)) !=null){ 
                         dwr(result7);//分别为1 3,1,3 和 4 5,4,5 
                         dwr(regExp7.lastIndex);//分别为3和7 
                       } 
     String.match(reCat)            返回一个包含在字符串中的所有匹配 的数组 
                                               var toMatch = "a bat, a cat, a fAt baT, a faT cat"; 
                                               var reAt = /at/gi; //如果不加参数g,返回的数组只会包含一个匹配元素 
                                               var arrMatchs = toMatch.match(reAt); 
                                               返回一个数组["at","at","At","aT","aT","at"] 

     String.search(reCat)           与indexOf 类似,返回在字符串中出现的第一个 匹配的位置 ,全局匹配表达式g 在这里不起作 用    toMatch.search(reAt);//输出3 

     String.replace(matchStr, replaceStr)              
                                               用第二个参数替换 某个子串(第一个 参数)的所有匹配 . 第一个参数 既可以是匹配的字符串 ,也可以是用于匹配的一个正则表达式 , 
                                               返回是替换后的整个字符串 
                                               var sToChange = "The sky is red"; 
                                               var reRed = /red/; 
                                               sToChange.replace(reRed,"blue" );    //输出The sky is blue     

     String.split(reCat)              将字符串分割 成子串,作为数组 返回 
                                              var sColor = "red, blue, yellow"; 
                                              var reExp = /\,/; 
                                              var arrs = sColor.split(reExp);    //得到一个数组["red","blue","yellow" ]   注意逗号 在正则表达式有 
                                                                                                                        特殊含义 ,这边需要转义                

7.2  简单模式(元字符 ,字符类 ,量词 ) 
元字符      11个   ( ) [] {} \ ^ $ |  ? * + .       要匹配字符串中的元字符,需要转义   /\^/ 
注意var reMark = new RegExp("\\^"); 当正则表达式以非字面量的形式 表示时,所有的反斜杠"\" 都要用两个反斜杠"\\" 来替换. 
因为javascript字符串解析器会按照翻译\n 的 方式尝试翻译\?.为了保证不会出现这个问题,在元字符的前面加上两个反斜杠, 
我们称之为双重转义 .(不太懂这个解释,我的理解是\ 本身也是元字符,先要对它转义得到 "\" ,然后再用这个"\" 对接下来的元字符转义) 
预定义的特殊字符 
\t 
制表符 
\n 
换行符 
\r 
回车符 
\f 
换页符 
\a 
Alert 字符 
\e 
Escape 字符 
\cX 
与 X 相应 的控制字符 
\b 
回退字符 
\v 
垂直制表符 
\o 
空字符 



字符类   将一些字符放入方括号中 . 

1, 简单类      
   var toMatch = "a bat, a cat, a fAt baT, a faT cat"; 
   var reg = /[bcf]at/gi ; 
   var arrs = toMatch.match(reg);     返回的数组[“bat”, “Cat”, “fAt”, “baT”, “faT”, “cat”] 

2,负向类      可 以指定要排除的字符 ,^ 要在[ ] 里面 
   匹配除了 a 和b 以外的所有字符,那么这个字符类为[^ab] . 脱字符^ 告诉正则表达式字符不能匹配后面 跟着的字符 
   只想获得包含at但不能以b或c开头的字符, /[^bc]at/gi 

3, 范围类 
   [a-z] 匹配所有小写字母 
   结合负向类可以排除给定范围内的所有字符 , 例如要排除字符1~4,可以使用类[^1-4] 

4, 组合类 
   [a-z1-9\n] 

5, 预定义类 
代码                  等同于                            匹配 
.                      [^\n\r]                         除了换行回车意外的任意字符 
\d                   [0-9]                             数字 
\D                   [^0-9]                           非数字 
\s                   [ \t\n\r\x0B\f]         空白字符 
\S                   [^ \t\n\r\x0B\f]       非空白字符 
\w                   [a-zA-Z_0-9]               单词字符(所有字母,数字和下划线) 
\W                   [^a-zA-Z_0-9]             非单词字符 


6, 量词 
用于指定某个特定模式出现的次数 
?                     出现0次或1次 
*                     出现0次或多次(任意次) 
+                     出现1次或多次(至少出现一次) 
{n}                 一定出现n次 
{n,m}             至少出现n次但不超过m次 
{n,}               至少出现n次 

贪婪的,惰性的,支配性的量词 
贪婪量 词 先看整个字符串是否匹配,如果没有发现匹配,它去掉该字符串中最后一个字符,并再次尝试.重复这个过程直到发现匹配 或者字符串不剩任何字符. 
             结合 下面会见到的两个例子, 实际过程可能是这样的: 
             第一步按上面的描述执行, 如果字符串不剩任何字符还是没有找到一个匹配, 那么删除字符串的第一个字符, 重复第一步. 
惰性量词 先看字符串中第一个字符是否匹配.如果单独这个 字符还不够,就读入下一个字符,组成两个字符的字符串.如果还是没有发现匹配,惰性量词继续从 
             字符串中添加字符直到发现匹配或者整个字符串都检查过也没有匹配.与贪婪量词的工作方式正好相反. 
支配量词 只尝试匹配整个字符串.如果整个字符串不能产生匹配,不 做进一步尝试.(IE不支持,Mozilla把支配量词当做贪婪的) 

贪婪              惰性                  支配                 描述 
?                   ??                    ?+                    零次或一次出现 
*                   *?                     *+                    零次或多次出现 
+                   +?                     ++                    一次或多次出现 
{n}               {n}?                 {n}+               恰好n次出现 
{n,m}           {n,m}?             {n,m}+            至少n次之多m次出现 
{n,}             {n,}?               {n,}+              至少n次出现 


7.3 复杂模式 
1, 分组 
分组是通过一系 列括号包围一系列字符,字符类以及量词来使用的. 
/(dog){2}/g       匹配dogdog 
/{[bd]ad?}*/     匹配ba, da, bad, dad 等 
去掉开头结尾的空白字符 
String.prototype.trim = function(){ 
   //注意, 分组里面.*?一定要是惰性的,不然这 个分组会把最后的空白字符也匹配进去 
   var reExtraStr = /^\s+(.*?)\s+$/ ; 
   return this.replace(reExtraStr,"$1"); 


2, 反向引用 
在 表达式计算完成之后,每个分组都被存放在一个特殊的地方以备将来使用.这些存储在分组中的特殊值,我们称之为反向引用( backreference). 
反向引用是按照从左到右遇到的左括号字符的顺序进行创建和编号的. 

反向引用的几种不同使用方法: 
* 使用正则表达式对象的test(), exec()方法后,反向引用的值可以从RegExp对象的构造函数中获得 
var toMarch = "#12345"; 
var regExp = /#(\d*)/; 
regExp.exec(toMarch); 
dwr(RegExp.$1); 
* 还可以直接在定义分组的表达式中包含反向引用,这可以通过使用特 殊转义序列如 \1 , \2 等实现. 
var toMarch2 = "dogdog"; 
var regExp2 = /(dog)\1/; 
dwr(regExp2.test(toMarch2)); 
* 反向引用可以用在String对象的replace()方法中 
var toMarch3 = "123123123 3211231231"; 
var regExp3 = /(\d+)\s*(\d+)/; 
var sNew = toMarch3.replace(regExp3,"$2 $1 "); //注意replace不改变原来的字符串,而是返回一个替换后的新 字符串 
dwr(sNew); 

3, 候选 
用一个管道符(| ),它放在两个单独的模式之间. 
var toMarch4 = "dog"; 
var toMarch5 = "cat"; 
var regExp4 = /dog|cat/; 
dwr(regExp4.test(toMarch4));//true 
dwr(regExp4.test(toMarch5));//true 

OR模式的一种通常用法是从用户输入中删除不合适的单词. 
var userInput = "badWord1asdasdandBadWord2"; 
var toMarch6 = /badword1|badword2/gi; 
var newStr = userInput.replace(toMarch6, function(march){ 
    return march.replace(/./g,"*"); 
}); 
dwr(newStr); //********asdasdand******** 

string.replace(regexp, replacement) 
replacement 既 可以是一个替换的字符串,也可以是一个function 
如果是function的情况, 这个function会为每一个匹配执行一次,这 个function的返回值作为最终替换的字符串. 
传给function的第一个参数是 第一个匹配的字符串; 
第二个参数是匹配字符串在原始字符串中的位置; 
第三个参数是原始字符串本身. 

4, 非捕获性分组 
创建反向引用的分组称为捕获性分组, 非捕获性分组不会创建反向引用. 
在较长的正则表达式中存储反向引用会降低匹 配的速度. 
要创建非捕获性分组,只要在左括号后面紧跟一个问 号和冒号. 
var str = "#123456"; 
var regE = /#(?: 123456)/; 
regE.test(str); 
dwr(RegExp.$1); //"" 

//去除所有的HTML标签 
String.prototype.skipHTML = function(){ 
   var regExp = /<(?:.|\s)*?>/g ; 
   return this.replace(regExp,""); 


5, 前瞻 
表示当某个特定的字符分组出现在另一个字符串之前时才去捕获它. 
前瞻分正向前瞻 和负向前瞻 , 正向前瞻检查的是接下来出现的是不是某个特定的字符集. 而负向前瞻则是检查接下来的不应该出现的特定字符集. 
正向前瞻需要将模式放在(?= 和 ) 之间,注意这不是分组,虽然它也用到 括号. 负向前瞻需要将模式放在(!= 和 ) 之间. 
var toMarch1 = "bedroom"; 
var toMarch2 = "bedding"; 
var bedReg = /(bed(?=room))/; 
dwr(bedReg.test(toMarch1)); //true 
dwr(bedReg.exec(toMarch1)); //bed,bed 因此这个正则表达式返回的第一个匹配是bed,而不是bedroom,但是它只会去匹配后面跟着 room的bed,有点搞 
dwr(RegExp.$1); //bed 
dwr(bedReg.test(toMarch2)); //false 

6, 边界 
边界用于正则表达式中表示模式的位置. 
^                    行开头 
$                    行结尾 
\b                  单词的边界 
\B                  非单词的边界 

查找一个出现在行尾的单词: 
var toMarch3 = "Important word is the last one."; 
var regExp3 = /(\w+)\.$/ ; //这边结合上面对贪婪量词的解释,有点不明白为何能匹配one?. 
regExp3.test(toMarch3); 
dwr(RegExp.$1);//one 

查找一个出现在行首的单词: 
var toMarch4 = "Important word is the last one."; 
var regExp4 = /^(\w+)/ ; //或者var regExp4 = /^(.+?)\b/; 
regExp4.test(toMarch4); 
dwr(RegExp.$1); 

抽取出所有的单词 
var toMarch5 = "First Second Third Fourth Fifth Sixth"; 
var regExp5 = /\b(\S+?)\b/g ; //或者 /\b(\S+)\b/g 和 /(\w+)/g 
var sArr = toMarch5.match(regExp5); 
dwr(sArr);//First Second Third Fourth Fifth Sixth 
注意这边如果用/(\w+?)/g 是不行的,这样得到的是一个一个的字母F,i,r,s,t,S... 

========================================================================================== 
与上面疑问类似的一个问题 
例子代码,如下: 
str = "abbb1234abbbaabbbaaabbb1234"; 
re = /.*bbb/g; 
alert(str.match(re));    //结果为abbb1234abbbaabbbaaabbb 
re = /.*?bbb/g; 
alert(str.match(re));    //结果为abbb,1234abbb,aabbb,aaabbb 
re = /a*bbb/g; 
alert(str.match(re));    //结果为abbb,abbb,aabbb,aaabbb 
re = /a*?bbb/g; 
alert(str.match(re));    //结果为abbb,abbb,aabbb,aaabbb 

对于第一、第二和第四个打印结果容易理解: 
第一个str.match(re),贪婪量词先匹配整个字串,若不匹配去掉一个尾字 符,继续匹配; 
第二个str.match(re),惰性量词从第一个字符开始递加去匹配,直到匹配成功,清空字串,从下一个 字符继续匹配。 
第四个str.match(re),同第二个。 

但第三个就不知道如何解释,如果按照第一个的方式去理解: 
先 匹配整个字串,发现不匹配,去掉尾字符,继续匹配...到最后,结果应该是abbb; 
而其结果却为abbb,abbb,aabbb,aaabbb 

以下为论坛解释 
对于第三个正则,就是这样来执行的; 
首 先清楚了是用了简单量词(*),而我们知道了*是贪婪量词: 
贪婪量词执行过程。正好楼主所说的那样。“先匹配整体,若不匹配则去掉尾字 符继续匹配,直到成功或者结束” 
这样说应说只能得到第一被匹配的对象。 
javascript 中的match返回的是所有匹配。 
对于要返回所有匹配。 
它还有第二个步:就是匹配成功后, 从最近的一个匹配后的下一个字符开始重新贪婪模式匹配。 重新执行它的步骤; 
例: 
str = "abbb1234abbbaabbbaaabbb1234"; 
re = /a*bbb/g; 
alert(str.match(re)); 

它的执行过程: 
第一步:首先整个字符串("abbb1234abbbaabbbaaabbb1234")匹配,发现匹配不成 功, 
接着。删除最后一个字符("4"),成了("abbb1234abbbaabbbaaabbb123"),这样依次执行 下去; 
执行...最后, 发现("abbb")可以被匹配了..所以生成第一个匹配值。 

但在这个match方法中是返回所有匹配。所以.. 
第二步:从最近的一个匹配(这里就是第一次匹配了)后的下一个字符开始重新贪婪模式 匹配.得到字符串是 
("1234abbbaabbbaaabbb1234"),然后。就按第一步执行。。 

执行完第一步 后。 
然后就从最近一次(这里就是第二次匹配了) 

....后面的过程就是重复一二步了。。 

但第二步时若继续按正则/a*bbb/g 去匹配“1234abbbaabbbaaabbb1234” 的话,应该是匹配不到才对吧? 
--------------------------------------------------- 
怎么匹配不到呢。。 
正 则表达式执行的时候。首先得找到前导字符(a), a是一个普通字符。普通字符,搜索的顺序为从左到右。。 
所以搜索 “1234abbbaabbbaaabbb1234”字符串时, 
得先匹配出a字符来"abbbaabbbaaabbb1234”, 
而 解析器又发现了a后面是一个贪婪字符。就按贪婪模式去匹配(从右到左) 

注意: /a*bbb/g 用到了全局匹配, 以上分析的症结所在可能就是因为一个"g" 
========================================================================================== 

7, 多行模式 
一下代码中的正则表达式想要匹配行末的一个单词.它只会匹配最后的Sixth, 但实际上这个字符串包含两个换行符,因此, Second, Fourth也应该匹配出来,因此引入了多行模式 
var toMarch6 = "First Second\nThird Fourth\nFifth Sixth"; 
var regExp6 = /(\w+)$/g; 
var sArr6 = toMarch6.match(regExp6); 
dwr(sArr6); 
要 引入多行模式,需要在正则表达式后面添加m 选项, 这会让$边界匹配换行符(\n) 和字符串真正的结尾. 
var regExp6 = /(\w+)$/gm; 

判 断日期的正则表达式: 
function isValidDate(s){ 
    var reDate = /(?:[1-9]|0[1-9]|[12][0-9]|3[01])\/(?:[1-9]|0[1-9]|1[0-2])\/(?:19\d{2}|20\d{2})/; 
    return reDate.test(s); 




-- 
Best Regards 
RicoYu 

分享到:
评论

相关推荐

    javascript正则表达式迷你书 (1).pdf

    JavaScript 正则表达式迷你书 本书是 JavaScript 正则表达式的入门级教程,旨在帮助读者快速掌握正则表达式的基本概念和应用。下面是本书的知识点摘要: 第一章:正则表达式字符匹配攻略 * 两种模糊匹配:横向...

    JavaScript正则表达式.ppt

    了解正则表达式概念 掌握正则表达式的语法 熟练掌握正则表达式在JavaScript中的应用

    精通正则表达式中文版英文版_中文版为扫描版

    书中的例子涵盖了多种编程语言,如Perl、Java、JavaScript、.NET等,这些语言的正则表达式引擎虽然大同小异,但在细节上有所区别,学习者将了解到如何在不同环境下应用正则表达式。 对于初学者,书中会引导他们理解...

    javascript正则表达式详解 (chm)

    javascript正则表达式详解 (chm)

    javascript正则表达式详解

    JavaScript正则表达式是JavaScript语言中一种极为重要的文本处理工具,它允许通过简洁的语法定义文本的匹配模式。这些模式可用来对字符串进行检索、替换、提取等操作。了解和掌握JavaScript正则表达式,对于提高...

    常用Javascript正则表达式汇总

    JavaScript中的正则表达式是一种强大的文本处理工具,用于在字符串中进行模式匹配和搜索替换。以下是一些常见的JavaScript正则表达式及其应用: 1. **匹配中文字符**:`[\u4e00-\u9fa5]` 这个正则表达式用于匹配...

    javascript正则表达式表单验证大全

    ### JavaScript正则表达式在表单验证中的应用详解 在Web开发中,表单验证是确保数据质量和用户体验的重要环节。JavaScript正则表达式提供了一种强大的工具,用于前端数据校验,确保用户输入的数据格式正确无误。...

    JavaScript常用正则表达式

    正则表达式(Regular Expression)是JavaScript中的一种强大工具,用于匹配字符串中的模式。在JavaScript中,正则表达式可以用来验证用户输入,例如检查邮箱地址的有效性或手机号码的格式。以下是一些JavaScript中...

    《精通正则表达式第三版 E文》

    本书第三版涵盖了各种正则表达式引擎的通用特性,包括Perl、Java、JavaScript、.NET、PCRE(Perl兼容正则表达式)等。书中不仅讲解了基本的匹配元素,如字符类、量词、位置锚点,还涉及更高级的主题,如后向引用、...

    javascript常用正则表达式大全

    javascript常用正则表达式大全,基本覆盖基本需求的正则表达式

    JavaScript正则表达式使用详解.zip

    JavaScript正则表达式是编程语言JavaScript中的一个重要组成部分,它用于处理文本字符串,执行模式匹配和字符串操作。在JavaScript中,正则表达式被广泛应用于数据验证、搜索与替换以及提取字符串中的特定信息等多个...

    常用正则表达式大全.txt

    根据提供的文件信息,我们可以整理出一系列与正则表达式相关的知识点。这些知识点涵盖了从基本的数字验证到复杂的字符串匹配等多个方面。下面是详细的知识点总结: ### 基本概念 正则表达式是一种用于文本模式匹配...

    三目运算符+正则表达式

    在编程世界中,三目运算符和正则表达式是两个非常重要的概念,它们各自扮演着独特的角色,同时也常被结合起来使用,以提高代码的简洁性和效率。让我们深入探讨这两个主题。 首先,三目运算符,也称为条件运算符,是...

    《学习正则表达式》高清扫描版 PDF

    正则表达式是程序员必备的强大工具,得到了各种Unix实用程序,以及Perl、Java、JavaScript、C#等编程语言的支持。读完本书,你会对正则表达式的常用语法了然于胸。掌握正则表达式是提升编程效率、节约时间的一大法.....

    经典JavaScript正则表达式实战

    经典JavaScript正则表达式实战 目录 1. 正则表达式实战...1 2. 匹配结尾的数字...2 3. 统一空格个数...3 4. 判断字符串是不是由数字组成...3 5. 电话号码正则...3 6. 手机号码正则表达式...4 7. 使用正则...

    javascript 30分钟学会正则表达式

    在JavaScript的世界里,正则表达式(Regular Expression)是一种强大的文本处理工具,它能用于搜索、替换、验证字符串等操作。对于任何JavaScript开发者来说,掌握正则表达式都是至关重要的,因为它们在处理数据格式...

Global site tag (gtag.js) - Google Analytics