Javascript 正则表达式教程详解

发布时间:2020-11-15编辑:脚本学堂
本文介绍下,javascript中正则表达式的全面知识,有理论,有实例,适合初学的朋友参考,当然中等水平的朋友,这篇文章仍然适用。走过路过的莫错过,朋友们。

正则是匹配字符串特定模式的一种表达式,官方是这样说的,但我的理解不外乎就是匹配字符窜嘛。

比如我们要验证邮箱,试想一下如果我们不用正则来匹配,直接用代码,循环,判断各种捣鼓来验证还真是一件非常麻烦的事情。如果用正则怎么来做了,就写伪正则来描述:   所有0-9或者a-z或者A-Z的字符出现一次到多次 加上(就是前面出现了的所有0-9...的字符跟上) "."或者"_"出现0次或者1次,然后在跟上 "@"符号 跟上 xxx.xx这种格式。
在下文的某个位置我会专门一步一步分析几个非常复杂的正则表达让大家能够很快的明白正则的语义。

  上面举了一个邮箱地址的正则表达式,比如这一串:
 

/^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+.[a-zA-Z]{2,3}$/ ;
 

首先给大家介绍javascript经常使用正则的对象和方法:

  RegExp  这个是正则对象, 比如匹配字符串"1234"中的"23"可以这样玩:

(new RegExp("23")).test("1234"); //out true;

  当然正则对象还有一种写法:

var reg = /23/; reg.test("1234")  //out true;

  RegExp.test(String) ;      //这个方法上面的用上了,匹配字符串是否为指定格式

  RegExp.exec(String);      //返回查询的值
    

var str = "123 aa cat Cat caT";

    var reg = /cat/i;

    reg.exec(str); // out "cat" 如果有则返回,没有的话就返回null

  String.search(RegExp) ; // 返回索引位置,类似indexOf()

    var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
      var reCat = /cat/gi;
      alert(data.search(reCat));   //out "23"

  String.replace(RegExp, String); //  将字符串替换成另外一个字符窜,RegExp指定的格式,String要替换的字符串
  

  var str = "1234aa67aa89";
      var reg = /aa/gi;
      str.replace(reg, "") ; //out "12346789"

  String.split(RegExp) ;  // 将字符串拆分成数组
    

var str = "1234aa67aa89";
      var reg = /aa/gi;
      str.split(reg) ; //out [1234, 67, 89]

  String.match(RegExp);          //将指定格式的字符串以数组的方式返回
    

var data = "123123,213,12312,312,3,Cat,cat,dsfsdfs,";
      var reCat = /cat/gi;
        var arrMactches = data.match(reCat); // out ["Cat", "cat"]

  上面的的方法是在字符串过滤操作中经常用到的方法, 当然还有一些我没有全部列举出来,用到了在去差API也不迟,好了我们熟悉了操作正则的这些方法之后我们紧接着正则表达式了,所谓表达式意思就是用一些字符按照先后顺序组合在一起表示的一层含义,所以我们先要重正则表达式的元字符说起,其实元字符就相当于javascript语言的关键字,比如你定义变量不能这样干 var if = "xxxx"; 正则有一下一些元字符:{ [ ^ | $ ] } ? * + . 这些都是正则的元字符,这里我就不解释意思了,用到了时候再来分析。如果大家想知道可以找度娘

  字符类

  字符类是用于测试字符串的组合, 将一些字符放入方括号中,就可以有效的告诉正则表达式去匹配第一个,第二个,第三个...比如/[abc]/,这个又称之为简单类
简单类:
 

var str = "cat 123 caT 234 cAt 345 CaT";
var reg = /cat/gi;
str.match(reg) ; //out ["cat", "caT", "cAt", "CaT"]
 

 
负向类和范围类: 这里要解释下"^" "-"这两个符号, "^"这个符号的意思就是取反,而"-"是范围, g表示全局,i表示忽略大小写,/[^2-3a-z]+/gi 所以这句话的意思就是: 除了2到3和a到z的所有字符出现1次到多次,并且在全局中忽略大小写。其实细心的看官这里还会发现一个知识点, 2-3a-z这一句其实是一个组合,又称之为组合类,下面的这个实例就用到了正则的几个知识点: 1.负向类,意思就是取反; 2. 范围类; 3.组合类,相当于逻辑运算符的并且&&
 

var str = "cat123caT234cAt345CaT";
var reg = /[^2-3a-z]+/gi;
str.match(reg);  //out ["1", "4", "45"]

预定义类:
 

代码   等同于        匹配
.     [^nr]      除了换行和回车符之外的任意字符
d    [0-9]        数字
D    [^0-9]       非数字字符
s    [tnx0bfr]           空白字符
S    [^tnx0bfr]          非空白字符
w    [a-zA-Z_0-9] 单词字符,所有的字符数字下划线
W    [^a-zA-Z_0-9]非单词字符

量词:量词是可以指某个特定模式出现的次数,可以是硬性量词,比如某个字符出现三次,也可以是软性量词,比如某个字符至少出现一次。正则中的量词有以下这些

贪婪量词:
 

?      出现零次到一次
+       至少出现一次或者多次
*        出现0次到多次
{n}    出现n次
{n,m}出现n次到m次
{n,}   至少出现n次或者n+次

  说道量词的话有贪婪, 惰性和支配量词,以上的这些量词都是贪婪量词,由于javascript正则引擎对支配量词支持不是很好,所以我们这里重点来说贪婪和惰性量词,先把惰性量词列出来之后在来说说他们的关系和区别

惰性量词:
  

??          出现零次到一次

  +?           至少出现一次或者多次

  *?出现零次到多次

  {n}?          出现n次

  {n,m}?      出现n次到m次

  {n,}?         至少出现n次或者n+次

  贪婪量词在匹配字符串的时候首先看是否匹配字符串,如果没有找到匹配的则去掉字符串中最后一个字符再次尝试,整个过程一直重复,直到字符串为空时停止。而惰性量词正好相反,首先查看字符串中第一个字符是否匹配,否则在读入下一个字符在进行匹配,直至重复这个过程到读入整个字符窜都不匹配时停止。可能说了这些多还是不太明白,下面我会举个例子帮助大家理解
 

var str = "abbbaabbbaaabbb1234";
var re1 = /.*bbb/g;   //贪婪匹配
var re2 = /.*?bbb/g;  //惰性匹配
alert(str.match(re1));
alert(str.match(re2));

  亲,你觉得第一个alert会输出什么呢,如果是[abb, aabbb, aaabbb]的话的, 那么恭喜你答错了,前面说过*是贪婪量词,它在匹配的时候会首先匹配整个字符串,是从字符串的尾部操作的,当去掉字符1的时候就发现剩下的字符串"abbbaabbbaaabbb"已经达到它匹配的要求了,所以它返回的结果就是字符串"abbbaabbbaaabbb", 而第二个alert为啥子会打印[abbb,aabbb,aaabbb]呢,我们再来一步一步的看,这个是惰性匹配,所以它在匹配字符串的时候是从字符串开始的部分取出第一个字符进行匹配,发现不行,在取下一个,还是不行,直至取到了"abbb".好,现在发现匹配了,然后将这个装进数组, 在从剩下的字符串里面取,直至最后将符合指定模式的子字符串装进数组,所以最后就返回[abbb,aabbb,aaabbb]。只要稍微花点心思动动手还是很容易就理解了。好了,关于正则的量词的一些知识点就讲到这里,万里长征才走一半,下面接到说正则的复杂模式,上面说到的字符类那一块都是正则的简单模式,只能做一些简单的字母,数字,汉字,长度等效验,如果在掌握了下面的复杂模式就可以非常牛逼的匹配各种复杂,蛋痛的字符串模式了,比如邮箱,身份证验证,标签过滤,包括jquery类选择器,sizzle引擎过滤器。好了,直接切入主题吧:
复杂分组

分组模式:分组模式就那么回事我用一个例子或许你一下子就豁然开朗了
 

//如果要匹配"andand"的怎么做呢,你也许会说可以这样干
var str = "asdfandandcxhksdf";
var reg = /andand/gi;
alert(reg.test(str)); //output true
//好的,亲,这样匹配也是可以的,但是有不知道多少and怎么办呢,
//不可能全部加在正则表达式里面吧,此时分组的便捷性就体现出了
//出了它的优势,我们可以这样干:
var reg = /(and){2}/g; //注意这里()是元字符分组的意思,{2} 是量词,贪婪量词

       

捕获分组模式:指的是RegExp.$1这个属性的值,这个值就是正则中一个分组的值,在这个对象RegExp中,定义了最多支持RegExp.$1-RegExp.$100个分组值,还是来个例子吧
 

var str = "asdffirstfirstsecondsecond1234";
var reg = /(first){2}(second){2}/gi;
reg.test(str); // 要必须匹配之后才有下面的值
alert(RegExp.$1); //output "first"
alert(RegExp.$2); //output "second"