JS 学习笔记--7---正则表达式

 

正则表达式中的内容很多,也很深,下面只是一些基本的知识点,练习中使用的浏览器是IE10,若有不当处请各位朋友指正,我会在第一时间修改错误之处。

匹配的概念:是包含的意思,不是相等的意思

1、正则表达式简介    

  在表单提交的时候需要用JS来对用户提交的数据进行验证,这样做的目的一是减少网络流量(尽可能的让提交到服务器端的数据时合法的,减少了客户端和服务器端数据交互),二是改善了用户的体验效果。    

  正则表达式可以在浏览器端进行数据验证的,也可以在服务器端用。当浏览器端数据验证通过以后,将数据提交到服务器端,服务器端还会有数据的验证和有效性处理,由于通过了客户端的验证,故可以节约大量的服务器端的系统资源。    

  正则表达式(regular expression)是一个描述字符模式的对象,ECMAScript中的RegExp类来表示正则表达式,并且String和RgeExp都顶一个使用正则表达式进行强大的模式匹配和文本检索替换等函数,如果遇到复杂的数据测试就需要用到正则表达式,比如验证URL地址、邮箱是否合法、从大量文本中提取有效信息等。    

  正则表达式在很多语言中都支持,而且实现方式也大体相同,元字符基本上是一样的,只是有些方法名可能不一样,正真的做到了跨语言的技术。   正则表达式的元字符见百度

2、正则表达式的创建     

  两种方法:new RegExp('...',[[i][m][g]]);和字面量方式 /.../[[i][m][g]];中括号表示可省    

  new方法的第一个参数是正则表达式的模式,后面第二个参数是从 igm 三个字母中选择任意字母组成的字符串[ig,im,gm,img 四种之一],称作为模式修饰符,并且模式修饰符的各个字符之间以及两边不能够有其他任何的字符,三个字母的书写顺序无所谓    

  字面量方式中两个反斜杠之内的值是正则表达式的模式,注意是不带引号的,如果写了引号则代表引号也是模式的组成成员,后面的模式修饰符和上面new方法一样,紧跟第二个反斜杠  

模式修饰符的可选参数
参数 含义 结果
i 忽略大小写 如果不写,默认的是区分大小写的
g 全局匹配 如果不写,结果是只要匹配到一个就返回
m 多行匹配 如果不写,则只是匹配一行
 

3、测试正则表达式    

  RegExp 对象提供了两种测试方法test()和exec()方法,基本功能是相似的,用于测试字符串的匹配。test()方法在字符串中查找是否存在指定的正则表达式并返回布尔值,如果存在就返回true,不存在就返回false;exec()方法也是在字符中查找指定的正则表达式,如果执行成功,则返回包含该查找字符串的相关信息数组(和分组有关),如果执行失败,则返回null。    

  通过测试得知,test()方法方法是只要匹配一次成功就返回,然后第二次执行的时候从第一次匹配成功的字符串之后开始查找,具体的可以参考练习中RegExp对象属性测试lastIndex    

  使用方式:pattern.test(str); pattern.exec(str); 返回值可以用于if的条件

4、使用字符串的正则表达式方法    

  除了上面的test()和exec()方法外,还有几个比较常用的String对象提供的几个方法 注:这些方法都是操作的值,不会改变字符串的本身,因为字符串具有不可变性,如果正则表达式中没有注明进行全局匹配的话,都默认只是匹配一个就返回,但是search永远是匹配第一个就返回  

String对象中的正则表达式方法
方法 含义 说明
str.match(pattern) 返回字符串str中复合模式pattern的子串或null 如果表达式没有设置成全局就只是返回第一个,设置成全局就按照数组返回所有
str.search(pattern) 返回字符串str中复合模式pattern的开始位置 从下标为0开始,查到就返回,没有全局之说,若没有找到就返回   -1
str.replace(pattern,replacement) 用replacement来替换字符串str中复合模式pattern的字符串 全部替换,返回替换后的字符串,源字符串不会被改变
str.split(pattern) 将字符串str按照模式pattern匹配后的子字符串进行分割 返回的是分割后的字符数组,源字符串不变
 

5、RegExp 对象中的静态属性    

  RegExp提供了一些静态属性,不需要声明对象就可以运行,但是不是所有浏览器都兼容      

  

RegExp对象的静态属性
属性 短名 含义 备注
input $_ 当前被匹配的字符串,就是源字符串 Opera不支持
lastMatch $& 最后一个被匹配的子字符串 Opera不支持
leftContext $` 最后一次匹配的前子串  
rightContext $' 最后一次匹配之后的子串 注意这个单引号前面要使用转义字符\
lastParen $+ 最后一对圆括号内的匹配子串 Opera不支持
multiline $* 用于指定是否所有表达式都用于多行的布尔值 IE、Opera不支持
 

  在使用这些静态属性之前必须要先执行一次正则表达式【pattern.test(str)/pattern.exec(str)都可以,但是这两个执行都只是匹配一次就返回,所以可能有的效果不明显,可以多执行几次】,只有执行一次后使用这些静态属性才有结果,alert(RegExp.input)即可    

  使用短名和前面属性是一样的效果,短名使用是通过 RegExp['$_']等来操作,同时input这个静态属性比较特殊,可以通过RegExp.$_ 来使用,其它的短名均不可以这样使用。  

        var pattern=/google/ig;
	var str="This Google is google ? Yes !";
	alert(RegExp.input);		//输出为空
	pattern.test(str);		//执行以下正则表达式	//其实这个测试是只要匹配一个就返回
	alert(RegExp.input);		//This Google is google ? Yes !
	alert(RegExp['$_']);		//This Google is google ? Yes !
	alert(RegExp.$_);		//This Google is google ? Yes !    

 

6、RegExp中的对象属性    

  RegExp提供了一些对象的实例属性,这是针对具体的正则表达式的属性,使用的很少  

RegExp 对象的实例属性
属性 含义 备注
global Boolean值,表示该正则表达式   g 是否已设置 设置为全局匹配返回为true,否则返回false
ignoreCase Boolean值,表示该正则表达式   i 是否已设置 设置为忽略大小写返回为true,否则返回为false
multiline Boolean值,表示该正则表达式   m 是否已设置 设置为多行匹配返回为true,否则返回为false
Source 正则表达式的源字符串形式 返回的就是字面量形式的反斜杠之内的字串,或者是new对象的第一个参数
lastIndex 整数,代表下次匹配将从哪里的字符位置开始(索引) 可以用多个test()执行,查看不同结果
 

  注:lastIndex 在获取下次匹配位置上IE和其他的浏览器有偏差,主要表现在非全局匹配上,lastIndex 还支持手动赋值。  

var pattern =/Box/ig;
	alert(pattern.global);		// true	是否设置为全局匹配	表示 g 是否已经设置
	alert(pattern.ignoreCase);	// true	是否设置为忽略大小写	表示 i 是否已经设置
	alert(pattern.multiline);	// false	是否设置为多行匹配		表示 m 是否已经设置
	alert(pattern.source);		// Box	返回的是正则表达式的源字符串形式

var str = "box and Box and box";
	//exec()一次只是匹配一条数据就返回
	pattern.exec(str);
	alert(pattern.lastIndex);	//3	上一条语句执行后匹配了一个box从这后面开始的第一个字符串,下标为3
	pattern.exec(str);		//再执行一次  匹配第二个box 后面的字符的索引为11
	alert(pattern.lastIndex);	//11
	pattern.lastIndex=13;		//设置下一次开始匹配的起始位置
	alert(pattern.lastIndex);	//13

 获取控件 一般简单的元字符的意思就不说明了 百度一大把

7、\b代表的是是否到达字符串的边界,和开始结尾标记符 ^,$ 有同样的含义;

   | 或匹配符,带有分组的意思,分隔供选择的字符.这个模式符使用的时候要注意它两边的内容是二选一,有时要注意用括号将其括起来;例如: /ab|cd|ef/ 匹配的是字符串 "ab",或者是字符串 "cd",又或者 "ef".

  {4,8}等这种用大括号阔气来的代表的是在这个大括号前面的分组或者某个字符匹配的次数

8、在模式中,用括号括起来的代表一个分组,分组的匹配模式是从外到里,从左到右进行匹配的。在模式中进行了分组,然后执行了一次正则表达式,就可以在后面使用匹配组里面的内容,用RegExp.$1可以直接输出第一个分组的内容,或者在字符串的替换方法str.replace()中可以直接用$1,$2等来表示分组对应的匹配子字符串,如str.replace(pattern,'A$1A'),就是直接在复合第一个分组的内容两边加上字母A;当多个分组的时候是从左到右依次用$1,$2,$3等来代表分组匹配的内容。

9、贪婪模式和非贪婪模式    

  贪婪模式:在保证整个模式匹配能够成功的情况下,有些表达式会尽可能多的匹配一些字符。    

  非贪婪模式:同样是在保证整个模式匹配成功的情况下,尽可能的少匹配字符。      

贪 婪  惰 性
+  +?
? ??
* *?
{n} {n}?
{n,} {n,}?
{n,m} {n,m}?
 

  有时如果要解决贪婪的问题,可能要开启全局匹配。

9、使用exec()方法,返回数组    

  上文中提到此方法是RegExp中提供的可以用来测试正则表达式的方法,如果成功会返回一个数组,而这个方法其实主要是针对在表达式中有分组的时候使用的。    

  这个方法返回的结果中,下标为0的元素就是匹配成功的整体字符串,从下标为1开始一直到后面,里面的内容是对应的每一个分组匹配的内容,也就是说下表为1的元素是模式中第一个分组匹配的结果,以此类推。第i个分组就对应的返回数组中下标为i的元素。    

  如果没有分组的时候返回的是整个匹配的字符串,也就是下标为0的字符串

10、捕获性分组和非捕获性分组    

  所谓的捕获性,我理解为就是需要返回分组所匹配的结果;

  而非捕获性则是不需要返回匹配的结果,有的时候却又必须要用一个分组来表示,比如在一个字符串的某一个部分可以有几组值,会需要用或匹配符来分割,而或匹配符如果不括起来会把它左边及右边当成两个组,而不是我们希望的只是某一部分相或,那就必须要用括号把个或分组符所分割的所有内容给括到一个括号内,但是由于不需要返回这个值,故可以用一个非捕获性分组。

  的分组都是捕获性分组非捕获性分组就是在前括号后面添加一个 ?: 就OK var pattern=/(\d+)(?:[a-z]+)/;执行后第二个分组内容不会返回

11、分组嵌套 :在一层分组中再添加一层分组,括号的嵌套 p=/(b(a(c)))/    

  分组嵌套中返回的时候也是先返回整个匹配的字符串,然后返回最外层的匹配结果,然后第二层的匹配结果,依次类推,先外后里    

  分析的时候可以先将分析的本层分组里面的所有分组视为无,也就是分析外层的时候就去掉本层里面所有嵌套的括号。 比如上面的模式 p.exec("bac");//返回的数组结果为:bac,bac,ac,c

12、前瞻匹配    

  就是在模式的匹配时候,某些字符后面必须更上一些特定的内容才能够匹配成功,比如字符串 "google" 中规定模式 goo 后面必须是 gle 才能够匹配成功,否则不匹配成功,就用到前瞻匹配    

  用括号将gle括起来放在goo后面,并且前括号后面写上 ?= 就OK 如:/goo(?=gle)/ 这样匹配的结果就只能够是字符串 google

13、特殊字符的处理    

  在特殊字符(比如:. ? \ [ ] * + 等)前面添加一个转义字符 \,使这些特殊字符失去特殊意义

14、换行匹配    主要是读取文本的时候,存在多行    

  模式一般都是针对一行,除非明确的在模式中添加了换行符,才会跨行匹配     如果要处理多行的数据,则需要开启多行模式并且还要开启全局匹配模式,否则只是匹配一次就会返回

15常用的一些正则表达式 许多常用的正则表达式,百度一下,

 

 练习代码:

  1 /*    表达式的创建
  2 
  3 // new RegExp()    方式创建
  4     var pattern = new RegExp('Reg');//创建一个模式,括号中的字符串就是模式字符串,它是将要检测数据的规范
  5     alert(pattern);        //输出结果是:/Reg/ 两个反斜杠就是字面量创建形式,中间是表达式
  6 
  7 //第二个可选参数为模式可选符,总共三个字符 i,g,m 顺序无所谓,不带有任何分隔符
  8 //模式可选字符代表的意义:i:忽略大小写,g:全文匹配,m:多行匹配(不写的话是只匹配第一行)
  9     var pattern = new RegExp('Reg',"igm");    
 10     alert(pattern);    //  /Reg/gim    //可选修饰符无论怎么写都是按照 gim 的顺序输出的
 11     //var pattern = new RegExp('Reg',"i,gm");    //error,这个参数只能是由 gim 组成的无序字符串
 12     var pattern = new RegExp('Reg',"mig");
 13     alert(pattern);    //  /Reg/gim
 14 
 15 
 16 //字面量创建方式    用两个反斜杠括起来,中间就写要匹配的表达式模式,第二个反斜杠后面跟上模式可选字符,同样不能用其他字符
 17     var pattern = /Reg/;    //创建一个模式字符串,注两个反斜杠中没有引号
 18     alert(pattern);    // /Reg/
 19     pattern=/Reg/im;
 20     alert(pattern);    //    /Reg/im    
 21     pattern = /"Reg"/gim;
 22     alert(pattern);    //  /"Reg"/gim
 23 
 24 //测试正则表达式    将需要检测的字符串用正则表达式进行收索匹配,看字符串中是否包含复合表达式规则的结果,
 25 // pattern.test(string);//test方法是测试字符串string中是否包含符合表达式的值,包含就返回true,否则返回false
 26     var pattern = new RegExp('Reg');
 27     var str='regexp';
 28     alert(pattern.test(str));//false    //因为表达式中是大写的 'Reg'
 29 
 30     var pattern =new RegExp("Reg",'i');// i 表示忽略大小写
 31     var str="regexp";
 32     alert(pattern.test(str));//true 因为表达式中的模式选择符说明了忽略大小写,字符串中包含小写的 'reg',故匹配成功
 33 
 34     var pattern=new RegExp("Reg",'i');
 35     var str="this is regexp!";
 36     alert(pattern.test(str));//true
 37 
 38     var pattern=/Reg/i;    //使用字面量创建表达式,设置模式为忽略大小写
 39     var str="This Is REGEXP !";
 40     alert(pattern.test(str));
 41 
 42 //使用字面量的方式一句话简化创建测试正则表达式        不推荐,容易误读,含义表达不清晰
 43     alert(/Reg/i.test("this is rgeohi "));//false
 44     alert(/Reg/i.test("this is regexp "));//true
 45 
 46 
 47 // pattern.exec() 方法  匹配成功后返回的是一个数组,匹配不成功返回的是null
 48     var pattern=/Reg/i;    //忽略大小写
 49     var str='abcdreghigkReghh';//这里面包含两个 reg 子字符串
 50     alert(pattern.exec(str));//reg    
 51     alert(typeof pattern.exec(str));    //object    数组的类型是object类型
 52     str='abcdegr';
 53     alert(pattern.exec(str));    //null
 54     alert(typeof pattern.exec(str));    // object    Null类型的字符串返回值为object
 55     var a=null;
 56     alert(typeof a);//object
 57 
 58 */
 59 
 60 /*    使用字符串的正则表达式方法   这些方法是String类型提供的,故使用方式上稍稍和上面两个方法不同
 61 
 62 //str.match(pattern);方法是字符串提供的匹配模式,然后以数组的形式返回匹配的所有结果(子字符串或者null)
 63     var pattern=/Box/ig;                //全局的忽略大小写的
 64     var str="this is a box,that is a Box??";
 65     alert(typeof str.match(pattern));// object    说明是数组
 66     alert(str.match(pattern));//box,Box
 67     pattern=/Box/i;                        //忽略大小写  非全局的
 68     alert(str.match(pattern));//box
 69     pattern=/Box/g;                        //全局的 区别大小写的
 70     alert(str.match(pattern));//Box
 71 
 72 //str.search(pattern); 返回的是字符串中匹配到的模式的子字符串的起始位置(下标为0开始的索引)
 73 //search方法是查找及返回  无需要全局
 74     var pattern=/Box/ig;
 75     var str="this is a box!This is a Box!!";
 76     alert(typeof str.search(pattern));    //number
 77     alert(str.search(pattern));            //10
 78     pattern=/Box/i;    //不全局匹配,忽略大小写
 79     alert(str.search(pattern));            //10
 80     pattern=/Box/g;    //区分大小写,匹配全局
 81     alert(str.search(pattern));            //24
 82 //没有查找到返回-1
 83     var pattern=/Bbx/ig;
 84     var str="this is a box!This is a Box!!";
 85     alert(typeof str.search(pattern));    //number
 86     alert(str.search(pattern));            //-1    没有查到
 87 
 88 //str.replace(patter,replacement);将字符串按照pattern模式进行匹配,然后将匹配到的子字符串替换成replacement子字符串
 89 //replace方法不会改变原来的原来的字符串的值
 90     var pattern =/Box/ig;
 91     var str ="this is box,that is a Box;;";
 92     alert(typeof str.replace(pattern,'XBox'));//string
 93     alert(str);                                  //"this is Box,that is a box;;"
 94     alert(str.replace(pattern,'XBox'));          //"this is XBox,that is a XBox;;"
 95     pattern=/Box/i;//不全局匹配,忽略大小写
 96     alert(str.replace(pattern,'XBox'));          //"this is XBox,that is a Box;;"
 97     pattern=/Box/g;    //区分大小写,匹配全局
 98     alert(str.replace(pattern,'XBox'));          //"this is box,that is a XBox;;"
 99 
100 //str.split(pattern);方法是将字符串按照pattern模式进行匹配然后按照匹配的子
101 //字符串为分隔符对源字符串进行分割,返回分割后的数组,元字符穿不会改变
102     var pattern =/Box/ig;
103     var str ="this is box!!that is a Box!!";
104     alert(typeof str.split(pattern));//object
105     alert(str.split(pattern));        //"this is ,!!that is a Box,!!";
106     alert(str);                        //"this is box!!that is a Box!!"
107     alert(str.split(pattern).length);//3    分割成3块
108 
109 */
110 
111 
112 /* RegExp 对象的一些静态属性和实例属性      
113 //静态属性是可以不实例化的属性,但是在这之前需要执行以下正则表达式,
114 //用短名操作的时候是写在中括号中用引号括气来的
115 //Opera浏览器只是支持 leftContext和rightContext  IE不支持multiline
116     var pattern=/google/ig;
117     var str="This Google is google ? Yes !";
118     alert(RegExp.input);        //输出为空
119     pattern.test(str);            //执行以下正则表达式    //其实这个测试是只要匹配一个就返回
120     //RegExp.input  返回的是当前被匹配的源字符串  $_ 是input的短名,效果是一样的
121     alert(RegExp.input);        //This Google is google ? Yes !
122     //用短名操作只是 input才可以用点的形式
123     alert(RegExp['$_']);        //This Google is google ? Yes !
124     alert(RegExp.$_);            //This Google is google ? Yes !
125     //RegExp.lastMatch 返回的是最后被匹配到的字符串
126     alert(RegExp.lastMatch);    //Google
127     alert(RegExp['$&']);
128     //返回最后一次匹配之前和之后的内容
129     alert(RegExp.leftContext);    //This 后面还有一个空格
130     alert(RegExp['$`']);
131     alert(RegExp.rightContext); // is google ? Yes !; 
132     alert(RegExp['$\'']);
133     //用于指定是否所有的表达式都用于多行的布尔值
134     alert(RegExp.multiline);    //undefined        IE不支持  在火狐中返回的时候false
135     alert(RegExp['$*']);
136     pattern=/(g)oogle/ig;
137     pattern.test(str);
138     //最后一对圆括号内匹配的字符串
139     alert(RegExp.lastParen);    //G
140     alert(RegExp['$+']);
141 
142 //下面是对象的实例属性    基本上没有用  
143     var pattern =/Box/ig;
144     alert(pattern.global);        // true        是否设置为全局匹配        表示 g 是否已经设置
145     alert(pattern.ignoreCase);    // true        是否设置为忽略大小写    表示 i 是否已经设置
146     alert(pattern.multiline);    // false    是否设置为多行匹配        表示 m 是否已经设置
147     alert(pattern.source);        // Box        返回的是正则表达式的源字符串形式
148 
149   //lastIndex在获取下一次匹配位置上IE和其他浏览器有偏差,主要表现在全局匹配上面
150     var pattern =/Box/ig;
151     var str = "box and Box and box";
152     //test一次只是匹配一条数据就返回
153     pattern.test(str);
154     alert(pattern.lastIndex);    //3        上一条语句执行后匹配了一个box从这后面开始的第一个字符串,下标为3
155     pattern.test(str);            //在执行一次  匹配第二个box 后面的字符的索引为11
156     alert(pattern.lastIndex);    //11
157     pattern.lastIndex=13;        //设置下一次开始匹配的起始位置
158     alert(pattern.lastIndex);    //13
159 
160     var pattern =/Box/ig;
161     var str = "box and Box and box";
162     //exec()一次只是匹配一条数据就返回
163     pattern.exec(str);
164     alert(pattern.lastIndex);    //3        上一条语句执行后匹配了一个box从这后面开始的第一个字符串,下标为3
165     pattern.exec(str);            //再执行一次  匹配第二个box 后面的字符的索引为11
166     alert(pattern.lastIndex);    //11
167     pattern.lastIndex=13;        //设置下一次开始匹配的起始位置
168     alert(pattern.lastIndex);    //13
169 
170 */
171 
172 
173 /*    提取字符    简单的元字符匹配就省略了  主要是针对分组
174 
175     var pattern=/goo gle/;        //直接用空格去匹配字符中的空格
176     var str='goo gle';
177     alert(pattern.test(str));//true
178 
179     var pattern=/goo\sgle/;        //用\s来匹配空格、制表符等
180     var str='goo gle';
181     alert(pattern.test(str));//true
182 
183 //    \b 表示到达边界
184     var pattern=/google\b/;        //\b表示到达边界  和开始结束符 ^、$功能类似
185     var str='googleg';
186     alert(pattern.test(str));    //false
187     str='google';
188     alert(pattern.test(str));    //true
189     pattern=/\bgoogle/;
190     alert(pattern.test(str));    //true
191     alert(pattern.test('ggoogle'));//false
192 
193 // | 或匹配选择模式符    
194     var pattern=/google|baidu|bing/;    // | 表示或匹配选择模式   是一个分组符
195     var str="this is baidu";    //匹配概念:是包含的意思  而不是相等的意思
196     alert(pattern.test(str));    //true
197     alert(pattern.test('soso'));//false
198 
199 //{4,8}表示的是前面这个字符或者说是分组分组匹配的次数
200     var pattern=/google{4,8}/;    //表示匹配e的4到8次
201     var str='googleeeeee';
202     alert(pattern.test(str));    //true
203 
204     var patter=/(google){4,8}/;        // google 使用括号括起来的,是一个分组,可以看成一个字符
205     var str='googlegooglegooglegoogle';    //表示 google 4-8次
206     alert(pattern.test(str));//true
207 
208     var pattern=/8.*8/;
209     var str='this is a 8google8';
210     alert(pattern.test(str)); // true
211 
212 // 一个括号代表一个分组,组可以用 $1,$2等来代替,编号是从1开始,而不是0开始
213 //当执行正则表达式后,$1 就代表的是第一个分组匹配的内容
214     var pattern=/8(.*)8/;
215     var str='this is a 8google8';
216     alert(pattern.test(str)); // true
217     alert(RegExp.$1);    //google    RegExp.$1表示获取模式中第一个分组对应的匹配字符串
218     document.write(str.replace(pattern,'<strong>$1</strong>'));
219     
220 //通过分组进行交换内容
221     var pattern=/(.*)\s(.*)/;    //两个分组
222     var str='google baidu';
223     alert(pattern.test(str));    //true
224     alert(str.replace(pattern,'$2 $1'));//交换位置  baidu google
225 
226 */
227 
228 /*
229 在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,
230 比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复
231 匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 "dxxxdxxxd",
232 就是贪婪模式
233 */
234 
235 /*    贪婪非贪婪模式(惰性模式)    贪婪:尽可能的多匹配一点  非贪婪:少匹配一点,让后面的尽快匹配
236 //对于贪婪模式解决的时候再后面添加一个 ? 就变成了非贪婪的模式了
237     var pattern=/[a-z]+/;    // + 就是一个贪婪模式
238     var str='abcd';
239     alert(str.replace(pattern,1));//1    贪婪下将所有的字符都给匹配上了,然后视为一个分组
240 
241     var pattern=/[a-z]+?/;    // +? 非贪婪模式
242     var str='abcd';
243     alert(str.replace(pattern,1));//1bcd    非贪婪模式,只是匹配了第一个字符
244 
245     var pattern=/[a-z]+?/g;    // +? 非贪婪模式 但是开启了全局
246     var str='abcd';
247     alert(str.replace(pattern,1));//1111    
248 
249 //贪婪模式下的结果
250     var pattern=/8(.*)8/;
251     var str= '8google8 8google8 8google8';    //匹配到了google8 8google8 8google
252     alert(str.replace(pattern,'<strong>$1</strong>'));
253     //结果是:<strong>google8 8google8 8google</strong>
254     //因为在匹配的过程中, . 元字符又可以表示任意的字符,而 * 又是一个贪婪模式匹配
255 
256 //使用惰性模式  为开启全局  
257     var pattern=/8(.*?)8/;    
258     var str= '8google8 8google8 8google8';    
259     alert(str.replace(pattern,'<strong>$1</strong>'));//<strong>google</strong> 8google8 8google
260     document.write(str.replace(pattern,'<strong>$1</strong>'));
261     //尽可能的让后面的匹配  故这次只是匹配了一个 8google8
262 
263 //使用惰性模式  开启了全局后  正确
264     var pattern=/8(.*?)8/g;        //开启全局
265     var str= '8google8 8google8 8google8';    
266     alert(str.replace(pattern,'<strong>$1</strong>'));
267     document.write(str.replace(pattern,'<strong>$1</strong>'));
268     //<strong>google</strong> <strong>google</strong> <strong>google</strong>
269 
270 //另外一种惰性  屏蔽了8的匹配,也就是两边包含字符
271     var pattern=/8([^8]*)8/g;        //开启全局
272     var str= '8google8 8google8 8google8';    
273     alert(str.replace(pattern,'<strong>$1</strong>'));
274     document.write(str.replace(pattern,'<strong>$1</strong>'));
275     //<strong>google</strong> <strong>google</strong> <strong>google</strong>
276 
277 //{m,n}{n}{n,}也是贪婪模式
278     var pattern=/[a-z]{2,5}/;//{2,5}也是贪婪模式  会尽可能的匹配到5个字符
279     var str='abcdefg';
280     alert(str.replace(pattern,'1'));    //1fg
281 
282     var pattern=/[a-z]{3}/;//{3}也是贪婪模式  会尽可能的匹配到5个字符
283     var str='abcdefg';
284     alert(str.replace(pattern,'1'));    //1defg
285 
286     var pattern=/[a-z]{3}/g;//{3}也是贪婪模式  会尽可能的匹配到5个字符
287     var str='abcdefg';
288     alert(str.replace(pattern,'1'));    //11g
289 
290     var pattern=/[a-b]?/;//{2,5}也是贪婪模式  会尽可能的匹配到5个字符
291     var str='abcdefg';
292     alert(str.replace(pattern,'1'));    //1fg
293 */
294 
295 /*    用 exec() 返回数组
296 //如果没有分组的时候返回的是整个匹配的字符串  其实就是返回的数组第1个元素
297     var pattern=/^[a-z]+\s[0-9]{4}$/;
298     var str='google 2014';
299     alert(pattern.exec(str));//gogle 2014
300     alert(pattern.exec(str)[0]);//gogle 2014
301 
302     var pattern=/[a-z]+/i;
303     var str='123abcdefg234';
304     alert(pattern.exec(str));//abcdefg
305     alert(pattern.exec(str)[0]);//abcdefg
306 
307 //返回的数组中 res[0]是匹配的整个字符串内容,res[1]开始一直往后是按照分组顺序来返回的
308     var pattern=/^([a-z]+)\s([0-9]{3,})([A-Z]+)$/;
309     var str='abcd 12345EFJH';
310     var res=pattern.exec(str)//
311     alert(res);//abcd 12345EFJH,abcd,12345,EFJH
312     alert(res.length);//4
313     alert(res[0]);    //abcd 12345EFJH    匹配的字符串
314     alert(res[1]);    //abcd    第一个分组
315     alert(res[2]);    //12345    第二个分组
316     alert(res[3]);    //EFJH    第三个分组
317 
318 */
319 
320 /*    捕获性分组和非捕获性分组    分组后需要返回匹配的分组信息,称为捕获分组,非捕获就是不需要返回,效率较高
321     var pattern=/(\d+)([a-z]+)/;    //返回所有的分组信息  为捕获性分组
322     var str='1234ahcd';
323     alert(pattern.exec(str));//1234ahcd,1234,ahcd
324     alert(pattern.exec(str).length);//3
325 
326     var pattern=/(\d+)(?:[a-z]+)/;    //不需要返回的分组中前面加一个 ?: 就是非捕获性分组
327     var str='1234ahcd';
328     alert(pattern.exec(str));//1234ahcd,1234
329     alert(pattern.exec(str).length);//2
330 
331 */
332 
333 /*    分组嵌套   外层分组中在添加两层分组,捕获的时候先外后里
334 //分析的时候从外向里分许,分析外层分组的时候,可以把里层分组的括号先去掉
335     var pattern=/(A+(B+(C+)))/;
336     var str='AABBCC';
337     alert(pattern.exec(str));        //AABBCC,AABBCC,BBCC,CC
338     alert(pattern.exec(str).length);//4
339     var res=pattern.exec(str);
340     alert(res[0]);    //AABBCC    匹配的字符串
341     alert(res[1]);    //AABBCC    返回的是匹配的第1个分组,从上面字符串来看就是外层分组,相当于是把里面两层分组给去掉的结果
342     alert(res[2]);    //BBCC        返回的是匹配的第二个分组,从上面字符串来看是第二层分组,相当于把最里面的一层分组给去掉的结果
343     alert(res[3]);    //CC        返回的是匹配的第三个分组,从上面字符串来看是最里面的一个分组
344 
345 */
346 
347 /*    使用前瞻匹配    就是模式的某些字符后面必须更上一些特定的内容才能够匹配
348 
349     var pattern=/goo/;        //非前瞻性匹配的正则表达式,只要包含goo都能够匹配
350     var str='this google';
351     alert(pattern.test(str));    //true
352     alert(pattern.exec(str));    //goo
353     str='this goo123';
354     alert(pattern.test(str));    //true
355     alert(pattern.exec(str));    //goo
356 
357     pattern=/goo(?=gle)/;        //前瞻性匹配的正则表达式,goo后面必须是gle
358     var str='this google';
359     alert(pattern.test(str));    //true
360     alert(pattern.exec(str));    //goo
361     str='this goo123';
362     alert(pattern.test(str));    //false
363     alert(pattern.exec(str));    //null
364 
365 
366     var pattern=/^[a-z]{3}([0-9]{4})/;
367     var str='cbadefg12345';
368     alert(pattern.test(str));//false
369 
370     str='abc1234';
371     alert(pattern.test(str));//true
372     alert(pattern.exec(str));//abc1234,1234
373     pattern=/^[a-z]{3}(?=0)([0-9]{2,})/;    //前瞻性匹配  要求在字符后面必须跟上一个0然后在是三个数值
374     alert(pattern.test(str));//false
375     alert(pattern.exec(str));
376 
377 */
378 /*    特殊字符   需要使用转义字符 \ 
379 
380     var pattern=/\.\[\/b\]/;//通过转义字符是 .、[、]不再是特殊的字符,而是匹配的字符串中包含的字符
381     var str='.[/b]';
382     alert(pattern.test(str));//true
383     alert(pattern.exec(str));//.[/b]
384     str='h8b8';
385     alert(pattern.test(str));//false
386 
387 */
388 
389 /*    使用换行匹配    主要是在读取文本的 时候  需要开启多行以及全局匹配才行
390 
391     var pattern=/^(\d)+/;    //用一个数子开头
392     str='1.baidu\n2.google\n3.bing';
393     alert(pattern.test(str));
394     alert(str.replace(pattern,'#'));
395     patter=/^(\d)+/g;
396     alert(str.replace(pattern,'#'));
397     pattern=/^(\d)+/m;
398     alert(str.replace(pattern,'#'));
399     //上面的结果都是一下   只是替换了首行
400     //#.baidu
401     //2.google
402     //3.bing
403     pattern=/^(\d)+/gm;
404     alert(str.replace(pattern,'#'));
405     //开启了全局和多行后替换了全部的数子
406     //#.baidu
407     //#.google
408     //#.bing
409 
410 */
View Code

 

posted on 2014-01-06 15:19  恋那片海  阅读(1457)  评论(1)    收藏  举报