Skip to content

Latest commit

 

History

History
140 lines (103 loc) · 5.93 KB

File metadata and controls

140 lines (103 loc) · 5.93 KB

正则表达式的模式匹配

1. 正则表达式的定义

1.1 直接量字符

正则表达式中的所有字母和数字都是按照字面含义进行匹配的。JavaScript正则表达式也支持非字母的字符匹配,这些字符需要通过反斜杠作为前缀进行转义

字符 匹配
字母和数字字符 自身
\o NUL字符(\u0000)
\t 制表符(\u0009)
\n 换行符(\u000A)
\v 垂直制表符(\u000B)
\f 换页符(\u000C)
\r 回车符(\u000D)
\xnn 由十六进制数nn指定的拉丁符,例如,\x0A等价于\n
\uxxxx 由十六进制数xxxx指定的Unicode字符,例如\u0009等价于\t
\cX 控制字符^X,例如\cJ等价于换行符\n

1.2 字符类

字符 匹配
[...] 方括号内的任意字符
[^...] 不在方括号内的任意字符
. 除换行符和其它Unicode行终止符之外的任意字符
\w 任何ASCII字符组成的单词,等价于[a-zA-Z0-9]
\W 任何不适ASCII字符组成的单词,等价于[^a-zA-Z0-9]
\s 任何非Unicode空白符
\S 任何非Unicode空白符的符号,注意\w和\S不同
\d 任何ASCII数字,等价于[0-9]
\D 除了ASCII数字之外的任何字符,等价于[^0-9]
[\b] 推格直接量(特例)

1.3 重复

字符 含义
{n,m} 匹配前一项至少n次,但不能超过m次
{n,} 匹配前一项至少n次或者更多次
{n} 匹配前一项n次
? 匹配前一项0次或者1次,也就是说前一项是可选的,等价于{0,1}
+ 匹配前一项1次或者多次,等价于{1,}
* 匹配前一项0次或者多次{0,}
  • 匹配2~4个数字:/\d{2,4}/
  • 精确匹配三个单词和一个可选数字:/\w{3}\d?/
  • 匹配前后带有一个或多个空格的字符串"java":/\s+java\s+/
  • 匹配一个或多个非左括号的字符:/[^(]*/

在使用“*”和“?”时要注意,由于这些字符可能匹配0个字符,因此它们允许什么都不匹配;例如,正则表达式/a*/实际上与字符串“bbbb”匹配,因为这个字符串含有0个a。

1.4 选择、分组和引用

  • 正则表达式的语法还包括指定选择项、子表达式分组和引用前一表达式的特殊字符。字符“|”用于分隔提供选择的字符

    /ab|cd|ef/可以匹配字符串“ab”,也可以匹配“cd”,还可以以匹配“ef”/\d{3}|[a-z]{4}/匹配的是三位数字或者四个小写的字母

    注意:选择项的尝试匹配是从左到右的,直到发现匹配项。如果左边的选择项匹配,就忽略右边的匹配,即使它产生更好的匹配,因此,当正则表达式/a|ab/匹配字符串“ab”时,只能匹配第一个字符

  • 正则表达式的选择、分组和引用字符

字符 含义
选择,匹配的是该符号左边的子表达式或右边的子表达式
(...) 组合,将几个项组成一个单元,这个单元可以通过“*”、“+”、“?”和“”等符号加以修饰,而且可以记住和这个组合相匹配的字符串供以后的引用使用
(?:...) 只组合,把项组合到一个单元,但不记忆与该组相匹配的字符串
\n 和第n个分组第一次匹配的字符想匹配,组是圆括号中的子表达式(也可能是嵌套的),组索引是从左到右的左括号数,“(?:”形式的分组不编码

1.5 指定匹配位置

字符 含义
^ 匹配字符串的开头,在多行检索中,匹配一行的开头
$ 匹配字符串的结尾,在多行检索中,匹配一行的结尾
\b 匹配一个单词的边界,简言之,就是位于符号\w和\W之间的位置,或位于字符\w和字符串的开头或者结尾之间的位置(需要注意,[\b]匹配的是退格符)
\B 匹配非单词边界的位置
(?=p) 零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符
(?!p) 零宽负向先行断言,要求接下来的字符不与p匹配

1.6 修饰符

字符 含义
i 执行不区分大小写的匹配
g 执行一个全局匹配,简言之,即找到所有的匹配,而不是在找到第一个之后就停止
m 多行匹配,^匹配一行的开头和字符串的开头,$匹配行的结束和字符串的结束

2. 用于模式匹配的String方法

  • search()方法。参数是一个正则表达式,返回第一个与之匹配的子串的起始位置,如果找不到匹配的子串,返回-1

    'Javascript'.search(/script/i)    //4
    
  • replace()方法。第一个参数是正则表达式,第二个是要进行替换的字符串

    text.replace(/javascript/gi,'JavaScript')
    
  • match()方法。唯一的参数就是一个正则表达式,返回的是一个由匹配结果组成的数组

    '1 plus 2 equal 3'.match(/\d+/g);	//["1", "2", "3"]
    
    • match返回一个数组a,那么a[0]存放的则是完整的匹配,a[1]存放的则是与第一个用圆括号括起来的表达式相匹配的子串,以此类推

      var url=/(\w+):\/\/([\w.]+)\/(\S*)/;
      var text='Visit my blog at http://www.example.com/~david';
      var result=text.match(url);
      console.log(result)  // ["http://www.example.com/~david", "http", "www.example.com", "~david"]
      if (result!=null) {
      	var fullurl=result[0];
      	console.log(fullurl);  //http://www.example.com/~david
      	var protocol=result[1]//http
      	var host=result[2];//www.example.com
      	var path=result[3];//~david
      }
      
  • split()方法,用以将调用它的字符串拆分为一个子串组成的数组,使用的分隔符值split的参数

    '123,456,789'.split(','); //["123", "456", "789"]
    
    '1,2,3,4,5,6,7'.split(/\s*,\s*/);	//["1", "2", "3", "4", "5", "6", "7"]
    

3. RegExp对象

方法

  • exec()方法,和match类似

    var pattern=/Java/g;
    var text='JavaScript is more fun than Java';
    var result;
    while((result=pattern.exec(text))!=null){
    	alert(result+' '+result[0]+' '+result.index);
    }
    
  • test()方法

      var pattern=/java/i;
      alert(pattern.test("Javascript")) //true