JavaScript正则表达式学习笔记[上]

正则表达式 Regular Expression

正则表达式是由一个字符序列形成的搜索模式,可用于所有文本搜索和文本替换的操作。[^1]它的重要性就不言而喻了。本文结合《JavaScript高级程序设计》一书并整理其他资料,对正则表达式的基础进行一个学习笔记的记录。更加详细的正则表达式学习心得将在之后的笔记中进行记录。

正则表达式构成

正则表达式由一些普通字符和一些元字符(metacharacters)组成。普通字符包括大小写的字母和数字,而元字符(用于匹配任何单个字符)则具有特殊的含义[^2]:

元字符
元字符 描述
. 匹配除“\r\n”之外任何单个字符;要匹配“\r\n”在内的任何字符,使用“[\s\S]”
\0 查找NULL字符
\b 匹配单词边界;也就是指单词和空格间的位置^3;例,“er\b”可匹配“never”的”er”
\B 匹配非单词边界;“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”
\cX 匹配由X指明的控制字符;X的值必须为A-Z或a-z之一*;否则,视为一个原义的“c”字符
\d 匹配一个数字字符;等价于[0-9]
\D 匹配一个非数字字符;等价于[^0-9]
\f 匹配一个换页符;等价于\x0c和\cL
\n 匹配一个换行符;等价于\x0a和\cJ
\r 匹配一个回车符;等价于\x0d和\cM
\s 匹配任何不可见字符;包括空格、制表符、换页符等;等价于[\f\n\r\t\v]
\S 匹配任何可见字符;等价于[^\f\n\r\t\v]
\t 匹配一个制表符;等价于\x09和\cI
\v 匹配一个垂直制表符;等价于\x0b和\cK
\w 匹配包括下划线的任何单词字符;该单词字符使用Unicode字符集
\W 匹配任何非单词字符;等价于“[^A-Za-z0-9_]”
\xdd 匹配十六进制dd转义值;十六进制转义值必须为确定的两个数字长
\n 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用
\uN 匹配N,其中N是一个用四个十六进制数字表示的Unicode字符
转义字符
转义字符 描述(若字符本身要出现,需在特殊字符前面加\)
\ 将下一个字符标记符、或一个向后引用、或一个八进制转义符
^ 匹配输入字符串开始位置;若设置了正则表达式的mFlag,^也匹配“\n”或“\r”之后的位置
$ 匹配输入字符串结束位置;若设置了正则表达式的mFlag,$也匹配“\n”或“\r”之前的位置
* 匹配前置子表达式任意次;例,zo*能匹配“z”,“zo”以及“zoo”,等价于”o{0,}”
+ 匹配前置子表达式大于等于1次;例,“zo+”能匹配“zo”以及“zoo”,等价于{1,}
? 匹配前置子表达式零次或一次。例,“do(es)?”可以匹配“do”或“does”,等价于{0,1}
. 匹配除“\r\n”之外任何单个字符;要匹配“\r\n”在内的任何字符,请使用像“[\s\S]”模式
将两个匹配条件进行逻辑“或”(Or)运算。注意:这个元字符不是所有的软件都支持的
量词类正则表达式
量词表达式 描述(若字符本身要出现,需在特殊字符前面加\)
n+ n为某pattern,匹配任何至少包含一个n的字符串
n* n为某pattern,匹配零个或者多个n的字符串
n? n为某pattern,匹配零个或者1个n的字符串
n{x} n为某pattern,匹配包含x个n的序列字符串
n{x,y} n为某pattern,匹配至少x个,最多y个n的字符串
n{x,} n为某pattern,匹配至少x个的字符串
获取/非获取以及正反向预查的正则表达式
获取/非获取RegExp 描述
(pattern) 匹配pattern并获取这一匹配;所获取的匹配可以从产生的Matches集合得到,请使用“(”或“)”匹配圆括号字符
(?:pattern) 非获取匹配;例,“industr(?:y ies)”
(?=pattern) 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95 98 NT 2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95 98 NT 2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern) 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95 98 NT 2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern) 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。
x y 匹配x或y。例如,“z food”能匹配“z”或“food”(此处请谨慎)。“[z f]ood”则匹配“zood”或“food”或” ood”。
[]范围类正则表达式
[]正则表达式 描述(只要[]中任意一个字符匹配就可以)
[0-9] 字符范围;匹配指定范围内的任意一个数字
[xyz] 字符集合;匹配所包含的任意一个字符。例,“[abc]”可以匹配“plain”中的“a”
[^xyz] 负值字符集合;匹配未包含的任意一个字符。例,“[^abc]”可以匹配“plain”中的“plin”
[a-z] 字符范围;匹配指定范围内的任意一个字符
[^a-z] 负值字符范围;匹配任何不在指定范围内的任意字符
其他类型
其他表达式 描述
\p{P} 小写p是property的意思,表示Unicode属性,用于Unicode正表达式的前缀。中括号内的“P”表示Unicode字符集七个字符属性之一:标点字符^4
\< > 匹配一个word的开始(\<)和结束(>)
( ) 将()内的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用\1到\9的符号来引用

语法

  • 直接量语法:

    1
    /pattern/flags;

    其中//包含的内部(pattern)是正则表达式字符串的主体;最后的flags是正则表达式的修饰标志,包含属性有g,i,m三种,分别是与全局匹配,不区分大小写匹配和多行匹配三种修饰标志。

    实例:

    1
    var patt = /[bc]at/i; //匹配第一个“bat”或”cat“,不区分大小写
  • 使用构造函数创建RegExp对象语法:

    1
    new RegExp(pattern, attributes);

    其中,pattern部分与上面直接量语法中的pattern相同,attributes是上面flags相同的标志;

RegExp实例的属性和方法

RegExp实例的属性

RegExp的每一个实例都具有下列属性,这些属性可以获取到该实例pattern的相关信息:

  • .global:bool值,表示是否设置了g标志
  • .ignoreCase:bool值,表示是否设置了i标志
  • .multiline:bool值,表示是否设置了m标志
  • .lastIndex:整数值,表示开始搜索下一个匹配项的自负位置,从0算起
  • .source:正则表达式的字符串表示,按照字面量形式而非传入构造参数中的字符串模式返回;
RegExp实例的方法
  • exec(),该方法是专门为捕获组而设计的:

    • 语法:RegExpObject.exec(testString)
    • 参数:接受一个参数,即要应用该模式的字符串;
    • 返回:包含第一个匹配项信息的数组(无匹配项时返回null);且返回值含有两个额外属性,index表示匹配项在字符串中的位置/input表示应用正则表达式的字符串;
    1
    2
    3
    4
    5
    6
    7
    8
    var testString = "mom and dad and baby";
    var pattern = /mom( and dad( and baby)?)?/gi;
    var matches = pattern.exec(testString);
    alert(matches.index); //0
    alert(matches.input); //"mom and dad and baby"
    alert(matches.[0]); //"mom adn dad and baby"
    alert(matches.[1]); //" and dad and baby"
    alert(matches.[2]); //" and baby"

    上述示例代码中,可以看到,返回的数组第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符串。关于“组”的相关内容请参考上一章节的表格中的/()/项。

    有关全局和非全局模式
    当pattern为全局模式时,每次调用exec()进行匹配时会返回下一个匹配项,即exec()调用过后,matches.index可能会增加,pattern.lastIndex也是同样会增加;如果pattern为非全剧模式时,每次调用exec()进行匹配时都会返回第一个匹配项。

  • test(),简单匹配。在不知道要进行匹配的文本内容情况下使用改方法比较好:

    • 语法:RegExpObject.test(testString);
    • 参数:接受一个参数,即要进行匹配的文本字符串;
    • 返回:如果字符串testString中含有与RegExpObject匹配的文本的话,就返回true,否则返回false;
RegExp构造函数属性

RegExp构造函数包含一些属性,这些属性适用于作用与众的所有正则表达式,并且基于所执行的最近一次正则表达式操作而变化。这些属性分别有一个长属性名和一个短属性名(Opera不支持短属性名):

长属性名 短属性名 说明
input $_ 最近一次要匹配的字符串
lastMatch $& 最近一次的匹配项
lastParen $+ 最近一次要匹配的捕获组
leftContext $` input字符串中lastMatch之前的文本
multiline $* 布尔值,表示是否所有表达式都是用多行模式
rightContext $’ input字符串中lastMatch之后的文本

其中,前三项是Opera没有实现的属性。使用这些属性能够从exec()和test()执行的操作中提取更具体的信息。

[^1]:From http://www.runoob.com/js/js-regexp.htm
[^2]:From http://baike.baidu.com/item/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F?sefr=enterbtn