正则JavaScript扫盲篇(好手勿进)

正则JavaScript扫盲篇(高手勿进)

正则表达式在jquery、linux等随处可见,已经无孔不入。因此有必要对这个工具认真的学习一番。本着认真、严谨的态度,这次总结我花了近一个月的时间。但本文无任何创新之处,属一般性学习总结。

一、思考

1. 案例

       通常系统管理员添加一个普通用户时,都有一些默认密码(如:123456),当新用户登录系统后需要自行修改密码为系统所要求的安全范围内的密码格式。如:密码位数要大于6位,必须是字母、特殊符号(如:下划线)、数字的组合形式。可以这样做:

Ø纯JavaScript实现

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. function sumt(){  
  2.         var p_count=0;//是否是则为数字、字母、下划线的组合形式  
  3.         var pwd=document.getElementById("txtPWD").value;  
  4.         //长度验证  
  5.         if(pwd.length<7){  
  6.             alert('密码长度必须大于6位!');  
  7.             return;  
  8.         }  
  9.         //数字验证  
  10.         for(var i=0;i<pwd.length;i++){  
  11.             var p_char=pwd[i];  
  12.             if(p_char>='0'&&p_char<='9'){  
  13.                 p_count++;  
  14.                 break;  
  15.             }  
  16.         }  
  17.         //字母验证  
  18.         for(var i=0;i<pwd.length;i++){  
  19.             var p_char=pwd[i];  
  20.             if(p_char>='a'&&p_char<='z'){  
  21.                 p_count++;  
  22.                 break;  
  23.             }  
  24.         }  
  25.         //特殊符号验证  
  26.         if(pwd.indexOf('_')!=-1){  
  27.             p_count++;  
  28.         }  
  29.          
  30.         if(p_count<3){  
  31.             alert('密码必须是数字、字母以及下划线组合形式!');  
  32.         }else{  
  33.             //提交  
  34.         }  
  35. }  

  

Ø正则实现

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. //正则实现  
  2. function sumt_reg(){  
  3.       var p_count=0;//是否是则为数字、字母、下划线的组合形式  
  4.       var val=document.getElementById("txtPWD").value;  
  5.       //长度验证  
  6.       if(val.length<7){  
  7.           alert('密码长度必须大于6位!');  
  8.           return;  
  9.       }  
  10.       var regex = /[0-9]/;//数字  
  11.       var regex1 = /[A-Za-z]/;//字母  
  12.       var regex2=/[_]/;//特殊符号  
  13.       if(val.match(regex)){  
  14.           p_count++;  
  15.       }  
  16.       if(val.match(regex1)){  
  17.           p_count++;  
  18.       }  
  19.       if(val.match(regex2)){  
  20.           p_count++;  
  21.       }  
  22.        
  23.       if(p_count<3){  
  24.           alert('密码必须是数字、字母以及下划线组合形式!');  
  25.       }else{  
  26.           //提交  
  27.       }  
  28. }  

  

2.了解正则

Ø概念

      正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

Ø起源

正则表达式[1]的“鼻祖”或许可一直追溯到科学家对人类神经系统工作原理的早期研究。美国新泽西州的Warren McCulloch和出生在美国底特律的Walter Pitts这两位神经生理方面的科学家,研究出了一种用数学方式来描述神经网络的新方法,他们创新地将神经系统中的神经元描述成了小而简单的自动控制元,从而作出了一项伟大的工作革新。

在1956 年,出生在被马克·吐温(Mark Twain)称为“美国最美丽的城市”之一的哈特福德市的一位名叫Stephen Kleene的数学科学家,他在Warren McCulloch和Walter Pitts早期工作的基础之上,发表了一篇题目是《神经网事件的表示法》的论文,利用称之为正则集合的数学符号来描述此模型,引入了正则表达式的概念。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“正则表达式”这个术语。

二、公共方法

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. function execReg(reg,str,msg){  
  2.  alert(msg+":"+reg.exec(str));  
  3.  //alert(msg+":"+str.match(reg));  
  4. }  
  5. var exampl_name;//实例名  
  6. var reg;//正则表达式  
  7. var str;//匹配字符  

  

 

三、字符集合

字符集合

说明

.

小数点可以匹配除了换行符(\n)以外的任意一个字符

\w

可以匹配任何一个字母或者数字或者下划线

\W

W大写,可以匹配任何一个字母或者数字或者下划线以外的字符

\s

可以匹配空格、制表符、换页符等空白字符的其中任意一个

\S

S大写,可以匹配任何一个空白字符以外的字符

\d

可以匹配任何一个 0~9 数字字符

\D

D大写,可以匹配任何一个非数字字符

 

1. example.1

小数点可以匹配除了换行符(\n)以外的任意一个字符

返回结果是l

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/./;  
  2. str='lixiuli';  
  3. exampl_name="example.1";  
  4. execReg(reg,str,exampl_name);  

  

 

2. example.2

\w小写

可以匹配任何一个字母或者数字或者下划线

返回结果是_

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/\w/;  
  2. str='_lixiuli';  
  3. exampl_name="example.2";  
  4. execReg(reg,str,exampl_name);  

  

 

3. example.3

\W大写,

可以匹配任何一个字母或者数字或者下划线以外的字符

返回结果是null

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/\W/;  
  2. str='_lixiuli';  
  3. exampl_name="example.3";  
  4. execReg(reg,str,exampl_name);  

  

4. example.4

\s小写

可以匹配空格、制表符、换页符等空白字符的其中任意一个

返回结果是空格

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/\s/;  
  2. str=' lixiuli';  
  3. exampl_name="example.4";  
  4. execReg(reg,str,exampl_name);  

  

5. example.5

\S 大写,

可以匹配任何一个空白字符以外的字符

返回结果是l

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/\S/;  
  2. str=' lixiuli';  
  3. exampl_name="example.5";  
  4. execReg(reg,str,exampl_name);  

  

6. example.6

\d 小写

可以匹配任何一个 0~9 数字字符

返回结果是5

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/\d/;  
  2. str='lixiuli520';  
  3. exampl_name="example.6";  
  4. execReg(reg,str,exampl_name);  

  

7.example.7

\D大写,

可以匹配任何一个非数字字符

返回结果是l

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/\D/;  
  2. str='lixiuli520';  
  3. exampl_name="example.7";  
  4. execReg(reg,str,exampl_name);  

 

四、量词,贪婪模式

量词:贪婪模式

说明

{n}

表达式固定重复n次,比如:"\w{2}" 相当于 "\w\w"

{m, n}

表达式尽可能重复n次,至少重复m次:"ba{1,3}"可以匹配 "ba"或"baa"或"baaa"

{m, }

表达式尽可能的多匹配,至少重复m次:"\w\d{2,}"可以匹配 "a12","x456"...

?

表达式尽可能匹配1次,也可以不匹配,相当于 {0, 1}

+

表达式尽可能的多匹配,至少匹配1次,相当于 {1, }

*

表达式尽可能的多匹配,最少可以不匹配,相当于 {0, }

 

1.example.8

{n}

表达式固定重复n(此处是2)次

结果是ww

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/w{2}/;  
  2. str='wusongti_ww';  
  3. exampl_name="example.8";  
  4. execReg(reg,str,exampl_name);  

  

2.example.9

{m,n}

表达式尽可能重复n(此处是3)次,

至少重复m(此处是1)次

结果是iii,而不是iiii

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i{1,3}/;  
  2. str='liiiixiuli';  
  3. exampl_name="example.9";  
  4. execReg(reg,str,exampl_name);  

  

3.example.10

{m,}

表达式尽可能的多匹配,

至少重复m(此处是2)次

结果是ii,而不是i

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i{2,}/;  
  2. str='lixiulii';  
  3. exampl_name="example.10";  
  4. execReg(reg,str,exampl_name);  

 

4.example.11

?

表达式尽可能匹配1次,

也可以不匹配

相当于 {0, 1}

结果是a,而不是null

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/a?/;  
  2. str='abbbccc';  
  3. exampl_name="example.11";  
  4. execReg(reg,str,exampl_name);  

 

  

5. example.12

+

表达式尽可能的多匹配,

至少匹配1次,

相当于 {1, }

结果是ii,而不是i

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i+/;  
  2. str='liixiuli';  
  3. exampl_name="example.12";  
  4. execReg(reg,str,exampl_name);  

 
 

6.example.13

*

表达式尽可能的多匹配,

最少可以不匹配,

相当于 {0, }

结果为iii,而不是null

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i*/;  
  2. str='iiilixiuli';  
  3. exampl_name="example.13";  
  4. execReg(reg,str,exampl_name);  

   

 

五、量词,非贪婪模式

量词:非贪婪

说明

{m, n}?

表达式尽量只匹配m次,最多重复n次。

{m, }?

表达式尽量只匹配m次,最多可以匹配任意次。

??

表达式尽量不匹配,最多匹配1次,相当于 {0, 1}?

+?

表达式尽量只匹配1次,最多可匹配任意次,相当于 {1, }?

*?

表达式尽量不匹配,最多可匹配任意次,相当于 {0, }?

 

1.example.14

{m, n}?

表达式尽量只匹配m次,

最多重复n次。

结果是i,而不是iiii

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i{1,3}?/;  
  2. str='liiiixiuli';  
  3. exampl_name="example.14";  
  4. execReg(reg,str,exampl_name);  

  

 

2.example.15

{m, }?

表达式尽量只匹配m次,

最多可以匹配任意次。

结果是ii,而不是iii

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i{2,}?/;  
  2. str='lixiuliii';  
  3. exampl_name="example.15";  
  4. execReg(reg,str,exampl_name);  

  

 

3.example.16

??

表达式尽量不匹配,

最多匹配1次,

相当于 {0, 1}?

结果是null,而不是a
+?

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/a??/;  
  2. str='abbbccc';  
  3. exampl_name="example.16";  
  4. execReg(reg,str,exampl_name);  

 

 

4.example.17

表达式尽量只匹配1次,

最多可匹配任意次,

相当于 {1, }?

结果是i,而不是ii

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i+?/;  
  2. str='liixiuli';  
  3. exampl_name="example.17";  
  4. execReg(reg,str,exampl_name);  

 

 

5.example.18

*?

表达式尽量不匹配,

最多可匹配任意次,

相当于 {0, }?

结果为null,而不是iii

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i*?/;  
  2. str='iiilixiuli';  
  3. exampl_name="example.18";  
  4. execReg(reg,str,exampl_name);  

   

 

 

六、字符边界

字符边界

说明

^

当前位置必须是文本开始位置

$

当前位置必须是文本结束位置

\b

当前位置的左右两侧,只能有一侧是字母数字或下划线

 

1.example.19

^

当前位置必须是文本开始位置

结果是null

 

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/^i/;  
  2. str='lixiuli';  
  3. exampl_name="example.19";  
  4. execReg(reg,str,exampl_name);  

   

 

2.example.20

$

当前位置必须是文本结束位置

结果是i

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i$/;  
  2. str='lixiuli';  
  3. exampl_name="example.20";  
  4. execReg(reg,str,exampl_name);  

 


 

3.example.21

\b

当前位置的左右两侧,

只能有一侧是字母数字或下划线

结果是i

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/i\b/;  
  2. str='lixiuli';  
  3. exampl_name="example.21";  
  4. execReg(reg,str,exampl_name);  

 
  

 

七、选择表达式

选择表达式

说明

|

使用竖线 "|" 分隔多段表达式,整个表达式可匹配其中任意一段。

1.example.22

|

返回结果为x

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/x|u/;  
  2. str='li.xiu.li';  
  3. exampl_name="example.22";  
  4. execReg(reg,str,exampl_name);  

 

 

八、自定义字符集合

自定义字符集合

说明

[ ]

用中括号 [ ] 包含多个字符,可以匹配所包含的字符中的任意一个。同样,每次只能匹配其中一个。

[^]

用中括号 [^ ] 包含多个字符,构成否定格式,可以匹配所包含的字符之外的任意一个字符。

1.example.23

[ ]

用中括号 [ ] 包含多个字符,

可以匹配所包含的字符中的任意一个。

同样,每次只能匹配其中一个。

结果是l

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/[\da-zA-Z]/;  
  2. str='lixiuli123LIXIULI';  
  3. exampl_name="example.23";  
  4. execReg(reg,str,exampl_name);  

 

 

2.example.24

[^ ]

用中括号 [^ ] 包含多个字符,

构成否定格式,

可以匹配所包含的字符之外的任意一个字符。

结果是l

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/[^i]/;  
  2. str='lixiuli';  
  3. exampl_name="example.24";  
  4. execReg(reg,str,exampl_name);  

   

 

九、分组

分组

说明

( )

用括号 ( ) 将其他表达式包含,可以使被包含的表达式组成一个整体,在被修饰匹配次数时,可作为整体被修饰。

另外,用括号包含的表达式,所匹配到的内容将单独作记录,匹配过程中或结束后可以被获取。

 

1.example.25

()

用括号 ( ) 将其他表达式包含,

可以使被包含的表达式组成一个整体,

在被修饰匹配次数时,

可作为整体被修饰。

另外,用括号包含的表达式,

所匹配到的内容将单独作记录,

匹配过程中或结束后可以被获取。

结果是lixiuliwusong,l,g

可以发现后面多出来一个l,g

这是因为括号的作用,原因在倒数第四行。

注:javascript不存在命名分组,我在这浪费了不少时间

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/^(i|l).+(g|i)$/;//匹配开头是i或l结尾是g或i的所有字符(除了换行符)  
  2. str='lixiuliwusong';  
  3. exampl_name="example.25";  
  4. execReg(reg,str,exampl_name);  

  

 

十、反向引用

反向引用

说明

/(子正则表达式)\编号/

反向引用标识由正则表达式中的匹配组捕获的子字符串。每个反向引用都由一个编号或名称来标识,并通过“\编号”表示法进行引用。

 

1.example.26

由此引出反向引用的使用

此处返回"l"

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/l/;//匹配l字母  
  2. str='lixiuli';  
  3. exampl_name="example.26";  
  4. execReg(reg,str,exampl_name);  

  

 

2.example.27

由此引出反向引用的使用

此处返回"lilu,li,llu"

lilu是整个正则匹配的结果

li是第一个括号匹配的结果

lu则是第二个括号匹配的结果

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/([a-z]{2})([a-z]{2})/;//匹配两个连续字母*2,即匹配四个连续字母  
  2. str='lilucy';  
  3. exampl_name="example.27";  
  4. execReg(reg,str,exampl_name);  

   

3.example.28

反向引用

此处返回"null"

因为第一个括号li,第二个括号也匹配了li

反向引用\1则是拿第一个括号的匹配结果去匹配剩余的字符

而剩余的字符没有li,因此返回null

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/([a-z]{2})([a-z]{2})\1/;  
  2. str='lililucy';  
  3. exampl_name="example.28";  
  4. execReg(reg,str,exampl_name);  

  

4.example.29

反向引用

此处返回"lililili,li,li"

lililili是整个正则匹配的结果

可将lililili分四部分来分析:li li li li

第一个li是第一个括号匹配到的

第二个li是第二个括号匹配到的

第三个li则是反向引用\1匹配到的

第四个li是反向引用\2匹配到的

第一个逗号后面的li是第一个括号匹配的结果

第二个逗号后面的li则是第二个括号匹配的结果

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. reg=/([a-z]{2})([a-z]{2})\1\2/;//反向匹配两个括号的内容  
  2. str='lililili';  
  3. exampl_name="example.29";  
  4. execReg(reg,str,exampl_name);  

   

 

十一、非捕获性分组

非捕获性分组

说明

(?:子表达式)

由于不是所有分组都能创建反向引用,有一种特别的分组称之为非捕获性分组,它是不会创建反向引用。反之,就是捕获性分组。要创建一个非捕获性分组,只要在分组的左括号的后面紧跟一个问号与冒号即可。

1.example.30

题目,移除所有标签,只留下innerText!

结果是:wusongti is a 大神

Js代码  正则JavaScript扫盲篇(好手勿进)
  1. var htmlText = "<p><a href='http://9080.iteye.com/'>wusongti</a> is a <em>大神</em></p>";  
  2. reg=/<(?:.|\s)*?>/g;  
  3. var text = htmlText.replace(reg, "");  
  4. alert(text)  

 

十二、其他

1.参考文献

Ø http://baike.baidu.com/view/94238.htm

Ø 《DEELX 正则引擎文档》

Ø 其他资料等

2.交流

Ø互动联系

本博文无任何创新之处,属于一般性自学总结。欢迎交流,734926878。