对前阵阅读学习正则表达式的基本概念等内容提取总结如下,既是对知识巩固,也便平日查阅。知识看懂了是一回事,真正应用熟练还须不断实践使用。

一、用途简述

  正则表达式是具有特殊语法的字符串,用来表示指定字符或字符串在另一个字符串中出现的情况。实际工作中,可以应用于数据有效性验证、查找替换文本、在文本或输入字段中提取特定文字。许多工具也都支持基于正则表达式的搜索替换。

二、组成部分

  上面说了正则表达式也是“字符串”(这个概念大家应该不陌生),最基本的正则表达式也就是普通字符串。

  js中有两种方法定义正则表达式:

1 var re = new RegExp("test");  //js中RegExp对象
2 var re = /test/;    //由一条斜线开始,跟着字符串模式,再另一条斜线结束

  以上定义的正则表达式可匹配字符串中出现的第一个单词test。如果匹配所有的test,可以加参数g。如下:

1  var re = new RegExp("test","g");
2  var re = /test/g;

有初步印象后,下来介绍正则表达式的基本概念;其中元字符、字符类和量词都是正则表达式语法中的重要组成部分。

    1. 普通匹配自身的字符

        大部分普通字符匹配自身。“普通”字符指字母、数字或空格。具体有:

        所有ASCII字母a~z和A~Z;

        ASCII数字0~9;

        空格字符;

        所有非ASCII字符;

        如下ASCII标点字符:! " # % ‘ ,  / :  ; < = > @ - ` ~(方言的不同,括号有所差异,某些正则表达式方言中,括号可以匹配自身)

    2. 元字符:

        元字符是正则表达式语法中的一部分,当我们要匹配元字符时,必须对其转义。正则表达式语法中用到的元字符有( [ { \ ^ $ | ) ? * + .

        如果要匹配(,则应该如下表示:

1 var re = new RegExp("\\(");
2 var re = /\(/;

        由于javaScript字符串解析器会按照翻译\n的方式尝试翻译\(,我们采用此种方式定义正则表达式时,须在元字符前加两个反斜杠(称为双重转义)。

    3. 特殊字符

        如果需要在正则表达式中使用特殊字符,可以直接使用字符本身,也可使用它们的ASCII代码或者Unicode代码。

        另处,还有一些其它的预定义特殊字符,如下表所示:         

字符  描述        

\n   换行符        

\r        回车符       

\t   制表符       

\f        换页符(Tab)      

\cX  与X对应的控制字符       

\b        退格符(BackSpace)        

\v        垂直制表符        

\0        空字符("")

        如果用RegExp构造函数来使用它们,则都须双重转义。

    4. 字符类:简单类,负向类,范围类,组合类,预定义类

        字符类用于测试字符的组合,将一些字符用括号([)包围起来,有效告诉正则表达式匹配我们需要的特定字符。        

    字符类[ ]的单位为单个字符,意思是字符类[ ]总是以字符为单位去匹配。

复制代码
 1 //简单类         
 2 
 3 var re = /[abc123]/;//将匹配abc123这6个字符中一个         
 4 
 5 //负向类         
 6 
 7 re = /[^abc]/;//将匹配除abc之外的一个字符         
 8 
 9 //范围类         
10 
11 re = /[a-b]/;//将匹配小写a-b 26个字母         
12 
13 re = /[^0-9]/;//将匹配除0-9 10个数字字符之外的一个字符         
14 
15 //组合类         
16 
17 re = /[a-b0-9A-Z_]/;//将匹配字母,数字和下划线
复制代码

    //预定义类

代码     等同于                 匹配

.        IE下[^\n],其它[^\n\r] 匹配除换行符之外的任何一个字符

\d       [0-9]                  匹配数字

\D       [^09]                  匹配非数字字符

\s       [ \n\r\t\f\x0B]        匹配一个空白字符

\S       [^ \n\r\t\f\x0B]       匹配一个非空白字符

\w       [a-zA-Z0-9_]           匹配单词字符(字母数字和下划线)

\W       [^a-zA-Z0-9_]          匹配非单词字符(除字母数字下划线之外的字符)

注:西方单词中,下划线也作为单词的一部分

5. 量词 (贪婪、惰性)

下表量词单个出现时皆是贪婪量词

代码     描述

*       匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。

+       匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。

?       匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。

{n}      n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。

{n,}     n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于                       'o+'。'o{0,}' 则等价于'o*'。

{n,m}     m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。 "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等    价于 'o?'。请注意在逗号和两个数之间不能有空格。

贪婪量词:

  先看整个字符串是不是一个匹配。如果没有发现匹配,它去掉最后字符串中的最后一个字符,并再次尝试。如果还是没有发现匹配,那么再次去掉最后一个字符串,这个过程会一直重复直到发现一个匹配或者字符串不剩任何字符。简单量词都是贪婪量词。

惰性量词:

  先看字符串中的第一个字母是不是一个匹配,如果单独着一个字符还不够,就读入下一个字符,组成两个字符的字符串。如果还没有发现匹配,惰性量词继续从字符串中添加字符直到发现一个匹配或者整个字符串都检查过也没有匹配。惰性量词和贪婪量词的工作方式恰好相反。

  使用惰性量词时,如果能停止则立即停止匹配。

1 var str = "abc";  
2 
3 var re = /\w+/;//将匹配abc  
4 
5 re = /\w+?/;//将匹配a 

通过在 '*'、 '+' 或 '?' 限定符后放置 '?',就从贪婪的变成了惰性的。

三、复杂模式

    1. 分组、反向引用(非捕获性分组)

      分组通过用一系列括号包围一系列字符、字符类及量词来使用。分组后就能使用重复操作符。

复制代码
 1 var re = /abc{2}/;//将匹配abcc     
 2 
 3 var re = /(abc){2}/;//将匹配abcabc     
 4 
 5 //上面的分组都是捕获性分组     
 6 
 7 var str = "abcabc ###";     
 8 
 9 var arr = re.exec(str);     
10 
11 alert(arr[1]);//abc     
12 
13 //非捕获性分组 (?:)     
14 
15 var re = /(?:abc){2}/;     
16 
17 var arr = re.exec(str);     
18 
19 alert(arr[1]);//undefined
复制代码

    更强大的是,可再表达式后反向引用分组。第一对括号匹配的是\1(RegExp对象的静态属性$1),第二对是\2(RegExp对象的静态属性$1),以此类推。

复制代码
1 var re = /(A?(B?(C?)))/; /*上面的正则表达式将依次产生三个分组 (A?(B?(C?))) 最外面的 (B?(C?)) (C?)*/
2 
3 var str = "ABC";
4 
5 re.test(str);//反向引用被存储在RegExp对象的静态属性$1—$9中
6 
7 alert(RegExp.$1+"\n"+RegExp.$2+"\n"+RegExp.$3); 
8 
9 re = /\d+(\D)\d+\1\d+/;//反向引用也可以在正则表达式中使用\1 ,\2...这类的形式使用
复制代码

   注1:RegExp.$1 - $9 返回九个在模式匹配期间找到的、最近保存的部分。只读。它是很脆弱的,为什么呢,因为它是全局的。所以在

使用了 exec 后,要获取 RegExp.$1 - $9 的值时,不要在中间夹杂其他的有关正则表达式的,比如 string 的 replace。

    注2:有时捕获一个子匹配是所希望的,有时则是不希望的。实际上,除非真的是需要捕获子匹配,否则请不要使用。由于不需要花时间和内存来存储那些子匹配,这种正则表达式的效率将更高。

    2. 候选、选择符 | (也就是所说的“或”)

    可以指定任何数目的候选项,选择符放于两个单独模式之间。    

1 var re = /(red|black|blue)/ //匹配red或者black或者blue

  3. 空白字符(html中)

html中可能出现的空白字符有如下几种:

空格本身、回车\r,换行\n,制表\t

通常hmtl中,用多种结合。

(1)使用[\r\n(\r\n)]匹配所有断行

(2)使用\s匹配所有空白和断行

   (3)使用^和$定位到一行的开头结尾

    4. 前瞻

    正向前瞻,用来捕获出现在特定字符之前的字符,只有当字符后面跟着某个特定字符才去捕获它。与正向前瞻对应的有负向前瞻,它用匹配只有当字符后面不跟着某个特定字符时才去匹配它。在执行前瞻和负向前瞻之类的运算时,正则表达式引擎会留意字符串后面的部分,然而却不移动index。

复制代码
 1 //正向前瞻
 2 
 3 var re = /([a-z]+(?=\d))/i;//我们要匹配后面跟一个数字的单词,然后将单词返回,而不要返回数字
 4 
 5 var str = "abc every1 abc";
 6 
 7 alert(re.test(str));//true
 8 
 9 alert(RegExp.$1);//every
10 
11 alert(re.lastIndex);//使用前瞻的好处是,前瞻的内容(?=\d)并不会当成一次匹配,下次匹配仍从它开始
12 
13 //负向前瞻(?!)
14 
15 re = /([a-z](?!\d))/;i //将匹配后面不包含数字的字母,并且不会返回(?!\d)中的内容
16 
17 str = "abc1 one";
18 
19 alert(re.test(str));
20 
21 alert(RegExp.$1);//one
复制代码

    5. 边界、位置

^  匹配输入字符串的开始位置。(如果^放在[]中,则表示负向类)

$  匹配输入字符串的结束位置。

/b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er/b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。

/B 匹配非单词边界。'er/B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

/A     文档的开头。

/Z      文档的结尾。

    6. 多行模式

        在正则表达式后添加m参数,则变为多行模式,这会让$边界匹配换行符\n以及字符串真正的结尾。同样多行模式会改变^边界的行为,它会匹配换行符之后的位置。

    本文多是对正则表达式概念的理解,日后可总结一些js中对正则表达式的支持,及在js中的实际使用情况。

posted on 2012-09-02 23:40  Kusion  阅读(168)  评论(0)    收藏  举报