非常教程

JavaScript参考手册

RegExp

RegExp

RegExp 构造函数创建了一个正则表达式对象,用于将文本与一个模式匹配。

有关正则表达式的介绍,请阅读 JavaScript指南中的正则表达式章节。

语法

字面量, 构造函数和工厂符号都是可以的:

/pattern/flags
new RegExp(pattern[, flags])
RegExp(pattern[, flags])

参数

pattern正则表达式的文本。flags

如果指定,标志可以具有以下值的任意组合:

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

描述

有两种方法来创建一个RegExp对象:一是字面量、二是构造函数。要指示字符串,字面量的参数不使用引号,而构造函数的参数使用引号。因此,以下表达式创建相同的正则表达式:

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

当表达式被赋值时,字面量形式提供正则表达式的编译(compilation)状态,当正则表达式保持为常量时使用字面量。例如当你在循环中使用字面量构造一个正则表达式时,正则表达式不会在每一次迭代中都被重新编译(recompiled)。

而正则表达式对象的构造函数,如new RegExp('ab+c')提供了正则表达式运行时编译(runtime compilation)。如果你知道正则表达式模式将会改变,或者你事先不知道什么模式,而是从另一个来源获取,如用户输入,这些情况都可以使用构造函数。

从ECMAScript 6开始,当第一个参数为正则表达式而第二个标志参数存在时,new RegExp(/ab+c/, 'i')不再抛出TypeError(“当从其他正则表达式进行构造时不支持标志”)的异常,取而代之,将使用这些参数创建一个新的正则表达式。

当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \)。比如,以下是等价的:

var re = /\w+/;
var re = new RegExp('\\w+');

正则表达式中特殊字符的含义

  • 字符类别(Character Classes)

  • 字符集合(Character Sets)

  • 边界(Boundaries)

  • 交替(Alternation)
  • 分组(grouping)与反向引用(back references)

  • 数量词(Quantifiers)

  • 断言(Assertions)

| 字符类别(Character Classes) |

|:----|

| Character | Meaning |

| . | (点号,小数点) 匹配任意单个字符,但是行结束符除外:\n \r \u2028 或 \u2029

在字符集中,点( . )失去其特殊含义,并匹配一个字面点( . )。

需要注意的是,m 多行(multiline)标志不会改变点号的表现。因此为了匹配多行中的字符集,可使用[^] (当然你不是打算用在旧版本 IE 中),它将会匹配任意字符,包括换行符。

例如,/.y/ 匹配 "yes make my day" 中的 "my" 和 "ay",但是不匹配 "yes"。 |

| \d | 匹配任意阿拉伯数字。等价于[0-9]

例如,/\d/ 或 /[0-9]/ 匹配 "B2 is the suite number." 中的 '2'。  |

| \D | 匹配任意一个不是阿拉伯数字的字符。等价于[^0-9]

例如,/\D/ 或 /[^0-9]/ 匹配 "B2 is the suite number." 中的 'B'。 |

| \w | 匹配任意来自基本拉丁字母表中的字母数字字符,还包括下划线。等价于 [A-Za-z0-9_]

例如,/\w/ 匹配 "apple" 中的 'a',"$5.28" 中的 '5' 和 "3D" 中的 '3'。 |

| \W | 匹配任意不是基本拉丁字母表中单词(字母数字下划线)字符的字符。等价于 [^A-Za-z0-9_]

例如,/\W/ 或 /[^A-Za-z0-9_]/ 匹配 "50%" 中的 '%'。|

| \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\w*/ 匹配 "foo bar" 中的 ' bar'。 |

| \S | 匹配一个非空白符。等价于 [^ \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\w*/ 匹配 "foo bar" 中的 'foo'。 |

| \t | 匹配一个水平制表符(tab) |

| \r | 匹配一个回车符(carriage return) |

| \n | 匹配一个换行符(linefeed)|

| \v | 匹配一个垂直制表符(vertical tab) |

| \f | 匹配一个换页符(form-feed) |

| \b | 匹配一个退格符(backspace)(不要与 \b 混淆) |

| \0 | 匹配一个 NUL 字符。不要在此后面跟小数点。 |

| \cX | X 是 A - Z 的一个字母。匹配字符串中的一个控制字符。

例如,/\cM/ 匹配字符串中的 control-M。|

| \xhh | 匹配编码为 hh (两个十六进制数字)的字符。|

| \uhhhh | 匹配 Unicode 值为 hhhh (四个十六进制数字)的字符。|

| \ u {hhhh}或\ u {hhhhh} | (仅当u标志被设置时)匹配Unicode值U + hhhh或U + hhhhh(十六进制数字)的字符。|

| \ | 对于那些通常被认为字面意义的字符来说,表示下一个字符具有特殊用处,并且不会被按照字面意义解释。

例如 /b/ 匹配字符 'b'。在 b 前面加上一个反斜杠,即使用 /\b/,则该字符变得特殊,以为这匹配一个单词边界。

对于那些通常特殊对待的字符,表示下一个字符不具有特殊用途,会被按照字面意义解释。

例如,* 是一个特殊字符,表示匹配某个字符 0 或多次,如 /a*/ 意味着 0 或多个 "a"。 为了匹配字面意义上的 * ,在它前面加上一个反斜杠,例如,/a\*/匹配 'a*'。|

| 字符集合(Character Sets) |

| 字符 | 含义 |

| xyz | 一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符'-'指定一个范围。

例如,[abcd] 等价于 [a-d],匹配"brisket"中的'b'和"chop"中的'c'。|

| ^xyz | 一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 '-' 指定一个范围内的字符。

例如,[^abc] 等价于 [^a-c]。 第一个匹配的是 "bacon" 中的'o' 和 "chop" 中的 'h'。 |

| 交替 |

| 字符 | 含义 |

| x | y | 匹配x或y。例如,/ green | red /匹配“青苹果”中的“绿色”和“红苹果”中的“红色”。|

| 边界(Boundaries) |

| 字符 | 含义 |

| ^ | 匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处。

例如,/^A/ 不匹配 "an A" 中的 "A",但匹配 "An A" 中的 "A"。|

| $ |匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处。

例如,/t$/ 不匹配 "eater" 中的 "t",但匹配 "eat" 中的 "t"。|

| \b | 匹配一个零宽单词边界(zero-width word boundary),如一个字母与一个空格之间。 (不要和 [\b] 混淆)

例如,/\bno/ 匹配 "at noon" 中的 "no",/ly\b/ 匹配 "possibly yesterday." 中的 "ly"。|

| \B | 匹配一个零宽非单词边界(zero-width non-word boundary),如两个字母之间或两个空格之间。

例如,/\Bon/ 匹配 "at noon" 中的 "on",/ye\B/ 匹配 "possibly yesterday." 中的 "ye"。|

| 分组(Grouping)与反向引用(back references) |

| 字符 | 含义 |

| (x) | 匹配 x 并且捕获匹配项。 这被称为捕获括号(capturing parentheses)。

例如,/(foo)/ 匹配且捕获 "foo bar." 中的 "foo"。被匹配的子字符串可以在结果数组的元素 [1], ..., [n] 中找到,或在被定义的 RegExp 对象的属性 $1, ..., $9 中找到。

捕获组(Capturing groups)有性能惩罚。如果不需再次访问被匹配的子字符串,最好使用非捕获括号(non-capturing parentheses),见下面。 |

| \n | n 是一个正整数。一个反向引用(back reference),指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串。

例如,/apple(,)\sorange\1/ 匹配 "apple, orange, cherry, peach." 中的 "apple,orange,"。一个更全面的例子在该表格下面。 |

| (?:x) | 匹配 x 不会捕获匹配项。这被称为非捕获括号(non-capturing parentheses)。匹配项不能够从结果数组的元素 [1], ..., [n] 或已被定义的 RegExp 对象的属性 $1, ..., $9 再次访问到。 |

| 数量词(Quantifiers) |

| 字符 | 含义 |

| x* | 匹配前面的模式 x 0 或多次。

例如,/bo*/ 匹配 "A ghost booooed" 中的 "boooo","A bird warbled" 中的 "b",但是不匹配 "A goat grunted"。|

| x+ | 匹配前面的模式 x 1 或多次。等价于 {1,}

例如,/a+/ 匹配 "candy" 中的 "a","caaaaaaandy" 中所有的 "a"。|

| x? | 匹配前面的模式 x 0 或 1 次。

例如,/e?le?/ 匹配 "angel" 中的 "el","angle" 中的 "le"。

如果在数量词 *+? 或 {}, 任意一个后面紧跟该符号(?),会使数量词变为非贪婪( non-greedy) ,即匹配次数最小化。反之,默认情况下,是贪婪的(greedy),即匹配次数最大化。

在使用于向前断言(lookahead assertions)时,见该表格中 (?=)、(?!) 和 (?:) 的说明。|

| x{n} | n 是一个正整数。前面的模式 x 连续出现 n 次时匹配。

例如,/a{2}/ 不匹配 "candy," 中的 "a",但是匹配 "caandy," 中的两个 "a",且匹配 "caaandy." 中的前两个 "a"。|

| x{n,} |n 是一个正整数。前面的模式 x 连续出现至少 n 次时匹配。

例如,/a{2,}/ 不匹配 "candy" 中的 "a",但是匹配 "caandy" 和 "caaaaaaandy." 中所有的 "a"。|

| x{n,m} | n 和 m 为正整数。前面的模式 x 连续出现至少 n 次,至多 m 次时匹配。

例如,/a{1,3}/ 不匹配 "cndy",匹配 "candy," 中的 "a","caandy," 中的两个 "a",匹配 "caaaaaaandy" 中的前面三个 "a"。注意,当匹配 "caaaaaaandy" 时,即使原始字符串拥有更多的 "a",匹配项也是 "aaa"。 |

| X*?X +?X??X {N}?X {N,}?X {N,M}?| 匹配前面的项目x,如上面的*,+,?和{...},但匹配是最小的可能匹配。例如,/<.*?>/匹配“<foo> <bar>”中的“<foo>”,而/<.*>/匹配“<foo> <bar>”。量词没有?据说是greedy。那些?被称为“non-greedy”。|

| 断言(Assertions) |

| 字符 | 含义 |

| x(?=y) | 仅匹配被y跟随的x。

举个例子,/Jack(?=Sprat)/,如果"Jack"后面跟着sprat,则匹配之。

/Jack(?=Sprat|Frost)/ ,如果"Jack"后面跟着"Sprat"或者"Frost",则匹配之。但是,"Sprat" 和"Frost" 都不会在匹配结果中出现。|

| x(?!y) | 仅匹配不被y跟随的x。

举个例子,/\d+(?!\.)/ 只会匹配不被点(.)跟随的数字。 /\d+(?!\.)/.exec('3.141') 匹配"141",而不是"3.141"。|

属性

RegExp.prototype允许为所有正则对象添加属性。RegExp.lengthRegExp.length 值为 2。

方法

全局对象RegExp 自身没有方法, 不过它会继承一些方法通过原型链

RegExp 原型对象和实例

属性

查看已废弃的RegExp属性

注意,RegExp 对象的几个属性既有完整的长属性名,也有对应的类 Perl 的短属性名。两个属性都有着同样的值。JavaScript 的正则语法就是基于 Perl 的。

RegExp.prototype.constructor创建该正则对象的构造函数。

RegExp.prototype.global是否开启全局匹配,也就是匹配目标字符串中所有可能的匹配项,而不是只进行第一次匹配。

RegExp.prototype.ignoreCase在匹配字符串时是否要忽略字符的大小写。

RegExp.prototype.lastIndex下次匹配开始的字符串索引位置。

RegExp.prototype.multiline是否开启多行模式匹配(影响 ^ 和 $ 的行为)。

RegExp.prototype.source正则对象的源模式文本。

RegExp.prototype.sticky是否开启粘滞匹配。

方法

RegExp.prototype.exec()在目标字符串中执行一次正则匹配操作。

RegExp.prototype.test()测试当前正则是否能匹配目标字符串。

RegExp.prototype.toSource()返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toSource 方法.

RegExp.prototype.toString()返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toString() 方法。

示例

使用正则改变数据结构

下例使用 replace 方法 (继承自 String)去匹配姓名 first last输出新的格式 last,first。脚本中使用 $1 和$2 指明括号里先前的匹配.

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

显示 "Smith, John".

使用正则表达式来分割具有不同行尾/行/换行符的行

默认行结束取决于平台(Unix,Windows等)。此示例中提供的线拆分可在所有平台上运行。

var text = 'Some text\nAnd some more\r\nAnd yet\rThis is the end';
var lines = text.split(/\r\n|\r|\n/);
console.log(lines); // logs [ 'Some text', 'And some more', 'And yet', 'This is the end' ]

请注意,正则表达式中的模式顺序很重要。

在多行中使用正则表达式

var s = 'Please yes\nmake my day!';
s.match(/yes.*day/);
// Returns null
s.match(/yes[^]*day/);
// Returns ["yes\nmake my day"]

使用带有 ”sticky“ 标志的正则表达式

该例展示了,如何在正则表达式上使用 sticky 标志,用来匹配多行输入的单独行。

var str = '#foo#';
var regex = /foo/y;

regex.lastIndex = 1;
regex.test(str); // true
regex.lastIndex = 5;
regex.test(str); // false (lastIndex is taken into account with sticky flag)
regex.lastIndex; // 0 (reset after match failure)

使用正则表达式和 Unicode 字符

正如上面表格提到的,\w 或 \W只会匹配基本的 ASCII 字符;如 'a' 到 'z'、 'A' 到 'Z'、 0 到 9 及 '_'。为了匹配其他语言中的字符,如西里尔(Cyrillic)或 希伯来语(Hebrew),要使用 \uhhhh,"hhhh" 表示以十六进制表示的字符的 Unicode 值。下例展示了怎样从一个单词中分离出 Unicode 字符。

var text = 'Образец text на русском языке';
var regex = /[\u0400-\u04FF]+/g;

var match = regex.exec(text);
console.log(match[0]);        // logs 'Образец'
console.log(regex.lastIndex); // logs '7'

var match2 = regex.exec(text);
console.log(match2[0]);       // logs 'на' [did not log 'text']
console.log(regex.lastIndex); // logs '15'

// and so on

这里有一个外部资源,用来获取 Unicode 中的不同区块范围:Regexp-unicode-block

从 URL 中提取子域名

var url = 'http://xxx.domain.com';
console.log(/[^.]+/.exec(url)[0].substr(7)); // logs 'xxx'

规范

Specification

Status

Comment

ECMAScript 3rd Edition (ECMA-262)

Standard

Initial definition. Implemented in JavaScript 1.1.

ECMAScript 5.1 (ECMA-262)The definition of 'RegExp' in that specification.

Standard

ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'RegExp' in that specification.

Standard

The RegExp constructor no longer throws when the first argument is a RegExp and the second argument is present. Introduces Unicode and sticky flags.

ECMAScript Latest Draft (ECMA-262)The definition of 'RegExp' in that specification.

Living Standard

浏览器兼容性

Feature

Chrome

Edge

Firefox (Gecko)

Internet Explorer

Opera

Safari

Basic support

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

Sticky flag ("y")

39 1

(Yes)

3.0 (1.9)

No support

(Yes) 2

10

Unicode flag ("u")

50

(Yes)

46 (46)

No support

?

10

RegExp(RegExp object, flags) no longer throws

??

?

39 (39)

No support

No support

No support

Feature

Android

Chrome for Android

Edge

Firefox Mobile (Gecko)

IE Mobile

Opera Mobile

Safari Mobile

Basic support

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

(Yes)

Sticky flag ("y")

No support

No support

?

1.0 (1.9)

No support

No support

No support

Unicode flag ("u")

?

?

?

46.0 (46)

?

?

?

RegExp(RegExp object, flags) no longer throws

No support

No support

?

39.0 (39)

No support

No support

No support

RegExp
regExp.@@match 详细
regExp.@@replace 详细
regExp.@@search 详细
RegExp.@@species 详细
regExp.@@split 详细
regExp.exec 详细
regExp.flags 详细
regExp.global 详细
regExp.ignoreCase 详细
regExp.lastIndex 详细
regExp.multiline 详细
RegExp.prototype 详细
regExp.source 详细
regExp.sticky 详细
regExp.test 详细
regExp.toString 详细
regExp.unicode 详细
JavaScript

JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络