则式(RegExp)
对象用于将文本与一个模式匹配。
有关正则表达式的介绍,请阅读 JavaScript指南中的正则表达式章节。
描述
字面量和构造函数
有两种方法可以创建一个 RegExp
对象:一种是字面量,另一种是构造函数。字面量由斜杠包围而不是引号包围。构造函数的字符串参数由引号而不是斜杠包围。
以下三种表达式都会创建相同的正则表达式:
/ab+c/i;
启 则式('ab+c', 'i');
启 则式(/ab+c/, 'i');
当表达式被赋值时,字面量形式提供正则表达式的编译(compilation)状态,当正则表达式保持为常量时使用字面量。例如当你在循环中使用字面量构造一个正则表达式时,正则表达式不会在每一次迭代中都被重新编译(recompiled)。
而正则表达式对象的构造函数,如 new RegExp('ab+c')
提供了正则表达式运行时编译(runtime compilation)。如果你知道正则表达式模式将会改变,或者你事先不知道什么模式,而是从另一个来源获取,如用户输入,这些情况都可以使用构造函数。
构造函数中的标志参数(flags)
从 ECMAScript 6 开始,当第一个参数为正则表达式而第二个标志参数存在时,new RegExp(/ab+c/, 'i')
不再抛出 TypeError
("从另一个RegExp构造一个RegExp时无法提供标志"
)的异常,取而代之,将使用这些参数创建一个新的正则表达式。
当使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \
)。
比如,以下是等价的:
var re = new RegExp("\\w+");
var re = /\w+/;
Perl-like RegExp 属性
请注意,{JSxRef(“RegExp”)}}属性有长名称和短名称(类似Perl)。两个名称总是引用同一个值。(Perl是JavaScript为其正则表达式建模的编程语言)。另请参见不推荐使用的RegExp属性。
构造函数
RegExp()
创建一个新的 RegExp
对象。
静态属性
get RegExp[@@species]
该构造函数用于创建派生对象。
则式.下位 – RegExp.lastIndex
该索引表示从哪里开始下一个匹配
实例属性
标 – RegExp.prototype.
flags
含有 RegExp
对象 flags 的字符串。RegExp.prototype.dotAll
.
是否要匹配新行(newlines)。RegExp.prototype.global
针对字符串中所有可能的匹配项测试正则表达式,还是仅针对第一个匹配项。RegExp.prototype.ignoreCase
匹配文本的时候是否忽略大小写。RegExp.prototype.multiline
是否进行多行搜索。RegExp.prototype.source
正则表达式的文本。RegExp.prototype.sticky
搜索是否是 sticky。RegExp.prototype.unicode
Unicode 功能是否开启。
实例方法
RegExp.prototype.compile()
(Re-)运行脚本的期间执行正则表达式。
执行() – RegExp.prototype.exec()
在该字符串中执行匹配项的搜索。
测试() – RegExp.prototype.test()
该正则在字符串里是否有匹配。RegExp.prototype[@@match]()
对给定字符串执行匹配并返回匹配结果。RegExp.prototype[@@matchAll]()
对给定字符串执行匹配,返回所有匹配结果。RegExp.prototype[@@replace]()
给定新的子串,替换所有匹配结果。RegExp.prototype[@@search]()
在给定字符串中搜索匹配项,并返回在字符串中找到字符索引。RegExp.prototype[@@split]()
通过将给定字符串拆分为子字符串,并返回字符串形成的数组。
转字串() – RegExp.prototype.toString()
返回表示指定对象的字符串。重写{JSxRef(“”Object.prototype.toString()“)}}方法。
示例
使用正则改变数据结构
下例使用 String
的 replace()
方法去匹配姓名 first last 输出新的格式 last, first。
在替换的文本中,脚本中使用 $1
和 $2
指明括号里先前的匹配.
let re = /(\w+)\s(\w+)/;
let str = "John Smith";
let newstr = str.replace(re, "$2, $1");
console.log(newstr);
这将显示 “Smith, John”.
使用正则来划分带有多种行结束符和换行符的文本
对于不同的平台(Unix,Windows等等),其默认的行结束符是不一样的. 而下面的划分方式适用于所有平台。
let text = 'Some text\nAnd some more\r\nAnd yet\rThis is the end'
let lines = text.split(/\r\n|\r|\n/)
console.log(lines) // logs [ 'Some text', 'And some more', 'And yet', 'This is the end' ]
注意正则表达式中的顺序是有意义的。
在多行中使用正则表达式
let s = "Please yes\nmake my day!";
s.match(/yes.*day/);
// Returns null
s.match(/yes[^]*day/);
// Returns 'yes\nmake my day'
使用带有 sticky 标志的正则表达式
The sticky flag
indicates that the regular expression performs sticky matching in the target string by attempting to match starting at RegExp.prototype.lastIndex
.
let str = '#foo#'
let 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)
sticky 标志和 global 标志的不同点
With the sticky flag y
, the next match has to happen at the lastIndex
position, while with the global flag g
, the match can happen at the lastIndex
position or later:
re = /\d/y;
while (r = re.exec("123 456")) console.log(r, "AND re.lastIndex", re.lastIndex);
// [ '1', index: 0, input: '123 456', groups: undefined ] AND re.lastIndex 1
// [ '2', index: 1, input: '123 456', groups: undefined ] AND re.lastIndex 2
// [ '3', index: 2, input: '123 456', groups: undefined ] AND re.lastIndex 3
// ... and no more match.
With the global flag g
, all 6 digits would be matched, not just 3.
使用正则表达式和 Unicode 字符
正如上面表格提到的,\w
或 \W
只会匹配基本的 ASCII 字符;如 a
到 z
、 A
到 Z
、 0
到 9
及 _
。
为了匹配其他语言中的字符,如西里尔(Cyrillic)或 希伯来语(Hebrew),要使用 \uhhhh
,hhhh
表示以十六进制表示的字符的 Unicode 值。
下例展示了怎样从一个单词中分离出 Unicode 字符。
let text = "Образец text на русском языке";
let regex = /[\u0400-\u04FF]+/g;
let match = regex.exec(text);
console.log(match[1]); // prints "Образец"
console.log(regex.lastIndex); // prints "7"
let match2 = regex.exec(text);
console.log(match2[1]); // prints "на" [did not print "text"]
console.log(regex.lastIndex); // prints "15"
// and so on
Unicode属性转义特性引入了一种解决方案,它允许使用像\p{scx=Cyrl}这样简单的语句。这里有一个外部资源,用来获取 Unicode 中的不同区块范围:Regexp-unicode-block
从 URL 中提取子域名
var url = "http://xxx.domain.com";
console.log(/[^.]+/.exec(url)[0].substr(7)); // logs "xxx"