开发者社区> 技术小胖子> 正文

javascript掌握正则表达式

简介:
+关注继续查看

最近利用一周时间阅读了《精通正则表达式(第3版)》前6章,希望能够精通正则表达式,并且能够撰写《javascript深度理解正则表达式》这样的文章。一周时间太短,我自认为仅仅是达到了“不再畏惧”、“更有信心”的程度,因而本文的目标只能是帮助读者“掌握”正则表达式。

我想正则表达式之所以难,主要体现在以下几个方面:
1)正则表达式的符号晦涩难懂
2)不支持排版(至少javascript目前还不支持)
3)不能设置断点,不能跟踪调试
4)没有真正的标准,不同工具所支持的正则表达式有许多细节上的差异

下文中如涉及正则表达式符号含义不明,请参阅<<javascript正则表达式入门笔记(完整版)>>

正则表达式本质上是一整套的处理字符串的模型,帮助人们利用简短的表达式来实现复杂的算法。早期的正则表达式引擎只有三百多行代码,发展到后来也不到1万行代码。打一个不恰当的比喻,利用正则表达式处理字符串,就像是利用SQL处理数据。正如我们在处理数据时要避免使用复杂SQL,我们在处理字符串时也应当避免使用复杂的正则表达式。下面是一段判断IP地址合法性的代码,比单纯用正则表达式要简单:


  1. var isIPAdress = function(IPStr){  
  2.     var pttrn = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;  
  3.     var IPObj = pttrn.exec(IPStr);  
  4.     var bool_result = false;  
  5.     if(IPObj){  
  6.         //添加进一步的识别规则  
  7.         if(IPStr==="0.0.0.0"){  
  8.             bool_result = false;  
  9.         }else if(IPStr==="1.1.1.1"){  
  10.             bool_result = false;  
  11.         }else if(IPObj[1]>=0 && IPObj[1]<=255 && IPObj[2]>=0 && IPObj[2]<=255 && IPObj[3]>=0 && IPObj[3]<=255 && IPObj[4]>=0 && IPObj[4]<=255){  
  12.             bool_result = true;  
  13.         }else{  
  14.             bool_result = false;  
  15.         }  
  16.     }  
  17.  
  18.     return bool_result;  

   调试信息: 
    isIPAdress("10.1.6.255")    true
    isIPAdress("1.1.1.1")    false
    isIPAdress("10.1.a.255")    false

浅议正则表达式的执行效率

执行下面这个javascript的正则表达式,比较ie/safari/firefox/chrome的执行效率,发现safari和firefox首次打开时较慢但是再刷新可做到瞬间完成,chrome和ie则是每次打开和刷新都慢,这说明javascript在ie和chrome上还是完全基于NFA算法做优化,safari和firefox则可能用到了DFA算法(也可能是缓存)。


  1. var p1 = /X(?:.+)+X/;  
  2. iJs.put(p1.exec("=XX==========================")); 

正则表达式对象:exec方法:

如果正则表达式使用了g作为后缀,则会记住上次执行的结果,执行时会找后面匹配。

如果正则表达式没有使用g作为后缀,则每次执行的结果相同,都是取第一个匹配上的。如果使用了捕获型括号,则匹配结果可通过1/2/3/...后缀获得,参见前面给出的判断IP地址合法性的代码。


  1. var pttrn = /bb/;  
  2. iJs.showObject(pttrn.exec("abaabbaaa"));  
  3. iJs.showObject(pttrn.exec("abaabbaaa"));  
  4. pttrn = /a+/g;  
  5. iJs.showObject(pttrn.exec("abaabbaaa"));  
  6. iJs.showObject(pttrn.exec("abaabbaaa")); 

调试信息:    

    [Object] bb
        |--[string] 0 ------------- bb
        |--[number] index ------------- 4
        |--[string] input ------------- abaabbaaa
        |--[number] lastIndex ------------- 6
    
    [Object] bb
        |--[string] 0 ------------- bb
        |--[number] index ------------- 4
        |--[string] input ------------- abaabbaaa
        |--[number] lastIndex ------------- 6
    
    [Object] a
        |--[string] 0 ------------- a
        |--[number] index ------------- 0
        |--[string] input ------------- abaabbaaa
        |--[number] lastIndex ------------- 1
    
    [Object] aa
        |--[string] 0 ------------- aa
        |--[number] index ------------- 2
        |--[string] input ------------- abaabbaaa
        |--[number] lastIndex ------------- 4

正则表达式对象:test方法

返回true或false


var pttrn = /bb/;   iJs.pt('pttrn.test("abaabbaaa")');   iJs.pt('pttrn.test("ababab")'); 

 调试信息: 
    pttrn.test("abaabbaaa")    true
    pttrn.test("ababab")    false

字符串对象:match方法

match方法返回一个对象,需注意如果正则表达式使用了后缀g,则捕获型括号会失效。


  1. var pttrn = /a(b)+/;  
  2. var pttrn_g = /a(b)+/g;  
  3. var myStr = "abaabbaaa";  
  4. var matchObj = myStr.match(pttrn);//捕获b  
  5. var matchObj_g = myStr.match(pttrn_g); //捕获失效 
  6.  
  7. iJs.pt("pttrn");  
  8. iJs.pt("pttrn_g");  
  9. iJs.pt("myStr");  
  10. iJs.showObject("matchObj");  
  11. iJs.showObject("matchObj_g"); 

 调试信息: 
    pttrn    /a(b)+/
    pttrn_g    /a(b)+/g
    myStr    abaabbaaa
    
    [Object] matchObj
        |--[string] 0 ------------- ab
        |--[string] 1 ------------- b
        |--[number] index ------------- 0
        |--[string] input ------------- abaabbaaa
        |--[number] lastIndex ------------- 2
    
    [Object] matchObj_g
        |--[string] 0 ------------- ab
        |--[string] 1 ------------- abb
        |--[number] index ------------- 3
        |--[string] input ------------- abaabbaaa
        |--[number] lastIndex ------------- 6

字符串对象:replace方法

如果replace第一个参数输入的是字符串或不带后缀的正则表达式,则只匹配替换一次。
只有正则表达是带后缀g才能替换全部。
第二个参数可以是函数,下面的例子中打印了函数接受的参数结构。第一个参数是匹配字符串、第二个参数开始是捕获字符串、然后跟着index、最后是字符串自己。

  1. var myStr = "abaabbaaabbb";  
  2. var searchValue = "a";  
  3. var searchRegExp = /a+/;  
  4. var searchRegExp_g = /a+/g;  
  5. var replaceValue = "X";  
  6. iJs.pt("myStr");  
  7. iJs.pt("searchValue");  
  8. iJs.pt("replaceValue");  
  9. iJs.pt("myStr.replace(searchValue,replaceValue)");  
  10. iJs.put("");  
  11.  
  12. iJs.pt("myStr");  
  13. iJs.pt("searchRegExp");  
  14. iJs.pt("replaceValue");  
  15. iJs.pt("myStr.replace(searchRegExp,replaceValue)");  
  16. iJs.put("");  
  17.  
  18. iJs.pt("myStr");  
  19. iJs.pt("searchRegExp_g");  
  20. iJs.pt("replaceValue");  
  21. iJs.pt("myStr.replace(searchRegExp_g,replaceValue)");  
  22. iJs.put("");  
  23.  
  24. var myStr_f = "a2aa22aaa222________";  
  25. var searchRegExp_g2 = /(a+)2/g;  
  26. var args;//全局变量便于iJs1捕获对象  
  27. var replaceFunction = function(a,b){  
  28.     var slice = Array.prototype.slice;  
  29.     args = slice.apply(arguments);  
  30.     iJs1.showObject("args");  
  31.     return args[0]+"+";  
  32. };  
  33. iJs.pt("myStr_f.replace(searchRegExp_g2,replaceFunction)"); 

 调试信息: 
    myStr    abaabbaaabbb
    searchValue    a
    replaceValue    X
    myStr.replace(searchValue,replaceValue)    Xbaabbaaabbb
    
    myStr    abaabbaaabbb
    searchRegExp    /a+/
    replaceValue    X
    myStr.replace(searchRegExp,replaceValue)    Xbaabbaaabbb
    
    myStr    abaabbaaabbb
    searchRegExp_g    /a+/g
    replaceValue    X
    myStr.replace(searchRegExp_g,replaceValue)    XbXbbXbbb
    
    myStr_f.replace(searchRegExp_g2,replaceFunction)    a2+aa2+2aaa2+22________

补充调试信息: 
    
    [Object] args
        |--[string] 0 ------------- a2
        |--[string] 1 ------------- a
        |--[number] 2 ------------- 0
        |--[string] 3 ------------- a2aa22aaa222________
    
    [Object] args
        |--[string] 0 ------------- aa2
        |--[string] 1 ------------- aa
        |--[number] 2 ------------- 2
        |--[string] 3 ------------- a2aa22aaa222________
    
    [Object] args
        |--[string] 0 ------------- aaa2
        |--[string] 1 ------------- aaa
        |--[number] 2 ------------- 6
        |--[string] 3 ------------- a2aa22aaa222________

字符串对象:search方法

search方法和indexOf方法类似,但是接受的是正则表达式对象,如果能够匹配,则返回首次匹配的首字符位置,如果不能匹配,则返回-1。此方法会忽略g标志。


  1. var myStr = "abaabbaaabbb";  
  2. var searchRegExp1 = /aaa/;  
  3. iJs.pt("myStr.search(searchRegExp1)");  
  4. var searchRegExp2 = /aXa/;  
  5. iJs.pt("myStr.search(searchRegExp2)"); 

调试信息: 
    myStr.search(searchRegExp1)    6
    myStr.search(searchRegExp2)    -1





 本文转自 hexiaini235 51CTO博客,原文链接:http://blog.51cto.com/idata/1113805,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
18051 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
23584 0
javascript正则表达式知识大全
什么是正则表达式 正则表达式(regular expression)是一个描述字符模式的对象。ECMAScript的RegExp类表示正则表达式,而String和RegExp都定义了使用正则表达式进行强大的模式匹配和文本检索与替换的函数。
813 0
javascript使用栈结构将中缀表达式转换为后缀表达式并计算值
1.概念   你可能听说过表达式,a+b,a+b*c这些,但是前缀表达式,前缀记法,中缀表达式,波兰式,后缀表达式,后缀记法,逆波兰式这些都是也是表达式。   a+b,a+b*c这些看上去比较正常的是中缀表达式,就是运算符放在两个操作数之间。
1155 0
javascript 表达式、括号、常用函数和jquery库怎么样实现的分析
(一)javascript表达式 表达式是什么?表达式是对变更进行赋值、更改或计算等操作的语句。它是变量、常量、操作符的综合。根据操作符的不类型,可以分为字符操作表达式、赋值表达式、逻辑表达式、关系表达式、自增自减表达式、位表达式等。
739 0
21117
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载