JavaScript 中的正则表达式

语法

在 JS 中,创建一个正则表达式的模式,可以有三种实现方式。

  • 字面量
  • 构造函数
  • 工厂符号
/pattern/flags
new RegExp(pattern [, flags])
RegExp(pattern [, flags])

其中,pattern 就是正则表达式(模式),flags 是模式修饰符。

下面的几种正则表达式的写法,创建的正则表达式都是相同的。

/ab+c/i;
new RegExp('ab+c', 'i');
new RegExp(/ab+c/, 'i');
RegExp(/ab+c/, 'i');

模式修饰符(flags)

在 JS 中的正则表达式,支持的修饰符主要有:

  • i 忽略大小写。
  • g 全局匹配。找到所有匹配,而不是在第一个匹配后停止。
  • m 多行模式匹配。开始和结束标记( ^ 和 $ )视为在多行上工作。也就是说,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不是只匹配整个目标字符串的最开始和最末尾处。
  • u 将模式视为 Unicode 序列。
  • y 粘性匹配。仅匹配目标字符串中此正则表达式的 lastIndex 属性指示的索引,并且不尝试从任何后续的索引匹配。

字符簇(Character Sets)

字符簇就是字符的集合(Character Sets),也叫字符集合。

字符簇的开始标记是 [ , 结束标记是 ] 。

例如,[abcd] 等价于 [a-d] 。

字符簇内部左侧的 ^ 表示对整个字符簇取反。例如,[^abc] 等价于 [^a-c]。

字符类别(Character Classes)

字符类别(Character Classes),可以用来表示某一类的字符。

  • . 点号表示匹配除换行符以外的任何字符。注意,在字符簇中,点号没有特殊含义。
  • \d 匹配任意的数字。等价于 [0-9] 。
  • \D 匹配任意的非数字。 等价于 [^0-9] 。
  • \w 匹配字母、数字、下划线。等价于 [A-Za-z0-9_] 。
  • \W 和 \w 相反。等价于 [^A-Za-z0-9_] 。
  • \s 匹配空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格。等价于 [ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​ \u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​​\u202f\u205f​ \u3000] 。
  • \S 匹配非空白符。
  • \t 匹配一个水平制表符(tab)。
  • \r 匹配一个回车符(carriage return)。
  • \n 匹配一个换行符(linefeed)。
  • \v 匹配一个垂直制表符(vertical tab)。
  • \f 匹配一个换页符(form-feed)。
  • [\b] 匹配一个退格符(backspace)(不要与 \b 混淆)。
  • \0 匹配一个 NULL 字符。不要在此后面跟小数点。
  • \cX X 是 A-Z 的一个字母。匹配字符串中的控制字符。例如,/\cM/ 匹配字符串中的 control-M。
  • \xhh 匹配编码为 hh (两个十六进制数字)的字符。
  • \uhhhh 匹配 Unicode 值为 hhhh (四个十六进制数字)的字符。

边界(Boundaries)

  • ^ 匹配整个字符串的头部,多行模式下也可以匹配行首。
  • $ 匹配整个字符串的尾部,多行模式下也可以匹配行尾。
  • \b 匹配一个零宽单词边界(zero-width word boundary),如一个字母和一个空格之间。例如,/\bno/ 匹配 "at noon" 中的 "no"。
  • \B 匹配一个零宽非单词边界(zero-width non-word boundary),如两个字母之间或两个空格之间。例如,/\Bon/ 匹配 "at noon" 中的 "on"。

分组(Grouping)

分组就是在整个正则表达式中拆分出子表达式,也称为子组。

子组的开始标记是 ( , 结束标记是 ) 。

捕获子组

(x) 表示捕获子组,也就是说,子组的匹配结果会被捕获。

console.log( "foobar".match(/(foo)bar/) )

// ["foobar", "foo", index: 0, input: "foobar", groups: undefined]

被匹配的子字符串可以在结果数组的元素 [1], ..., [n] 中找到,或在被定义的 RegExp 对象的属性 $1, ..., $9 中找到。

捕获子组会影响性能,如果不需要再次访问被匹配的子字符串,最好使用非捕获子组。

反向引用

\n 表示反向引用。

反向引用指的是对捕获子组的匹配结果(子字符串)的引用。

n 是一个正整数,指向的是正则表达式中第 n 个小括号(从左开始数)中的子组(子表达式)匹配到的子字符串。

非捕获子组

(?:x) 表示非捕获子组,表示不单独捕获子组的匹配结果。

console.log( "foobar".match(/(?:foo)bar/) )

// ["foobar", index: 0, input: "foobar", groups: undefined]

可选分支

x|y 表示匹配 x 或 y 。

例如,/green|red/ 会匹配 "green apple" 中的 green,也会匹配 "red apple" 中的 red 。

量词(Quantifiers)

量词用来指定匹配的个数(次数),也称作限定符。

  • {1} 限定次数为 1
  • {3} 限定次数为 3
  • {3,} 限定次数为 3 次及以上
  • {1,3} 限定次数为 1-3 次
  • ? 限定次数为 0 次或 1 次,等价于 {0,1}
  • * 限定次数为 0 次及以上,等价于 {0,}
  • + 限定次数为 1 次及以上,等价于 {1,}

量词可以对以下的元素的匹配次数进行限定。

  • 单独的字符,可以是经过转义的
  • 元字符
  • 字符簇
  • 反向引用
  • 子组

如果没有明确指定量词,默认匹配次数为 1 次

断言(Assertions)

只有当断言为 true 时,才进行匹配。

上面说到的 【边界】(Boundaries),就是一种最简单的断言。

断言指的是对某个位置的匹配作出假设。断言部分不会出现在匹配结果中。

  • x(?=y)

    仅匹配被 y 跟随的 x 。 /Jack(?=Sprat)/,如果 Jack 后面跟着 Sprat,则匹配 Jack 。但 Sprat 并不会出现在匹配结果中。

  • x(?!y)

    仅匹配不被 y 跟随的 x 。 /\d+(?!\.)/ 只会匹配不被点号 . 跟随的数字。 /\d+(?!\.)/.exec('3.141') 匹配的是 141,而不是 3.141 。

使用正则表达式

在 JavaScript 中, 使用正则表达式主要有两种形式。

  • RegExp 的 exec 和 test 方法
  • String 的 match、search、replace 和 split 方法

RegExp 的 exec 和 test 方法

exec() 方法,用当前的正则表达式来匹配目标字符串。匹配成功,返回数组;失败返回 null 。

var myRe = /d(b+)d/;
var myArray = myRe.exec("cdbbd");
console.log(myArray);

// ["dbbd", "bb", index: 1, input: "cdbbd", groups: undefined]

test() 方法,测试当前的正则表达式能否匹配目标字符串。它返回 true 或 false 。

var res = /d(b+)d/.test("cdbbd");
console.log(res);

// true

String 的 match、search、replace 和 split 方法

match() 方法的作用和 exec() 一样,只是写法有区别。它返回一个数组或者在未匹配到时返回 null 。

var str = "cdbbd";
var myArray = str.match(/d(b+)d/);
console.log(myArray);

// ["dbbd", "bb", index: 1, input: "cdbbd", groups: undefined]

search() 方法,测试正则表达式在目标字符串中首次匹配成功的位置。如果匹配成功,返回匹配到的位置索引;失败时返回 -1 。

var res = "cdbbd".search(/d(b+)d/);
console.log(res);

// 1

replace() 方法,表示正则替换。使用替换字符串替换掉匹配到的子字符串。

var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newStr = str.replace(re, "$2, $1");
console.log(newStr);

// Smith, John

split() 方法,表示用正则表达式或字符串来将目标字符串分割为数组。

var myArray = "a=b=c".split(/=/);
console.log(myArray);

// ["a", "b", "c"]
var myArray = "a=b=c".split('=');
console.log(myArray);

// ["a", "b", "c"]

猜你喜欢

转载自blog.csdn.net/lamp_yang_3533/article/details/80551503