正则表达式(Regular Expression)

首页 > JavaScript基本对象 > 正则表达式(Regular Expression)

目录

■ 一览

compile(), exec(), global, ignoreCase, index, input, lastIndex, lastMatch, lastParen, leftContext, match(), multiline, RegExp(), rightContext, source, $&, $', $*, $+, $_, $`, $n

正则表达式对象

regexp = new RegExp(patern[, flag])

生成正则表达式对象。正则表达式对象用在字符串的匹配上。下面的例子里,使用 match() 检查字符串 str 里有没有 "DEF" 。

str = "ABCDEFG";
re = new RegExp("DEF", "i");
if (str.match(re)) {
    alert("找到了DEF。");
}

为了符合面向对象中“数据类型都可以生成对象”的思想,JavaScript准备了new RegExp(),不过基本没什么人用。一般像下面这样写。

str = "ABCDEF";
if (str.match(/DEF/i)) {
    alert("找到了DEF。");
}

如果只是要判断“是否含有DEF”的话,用 index() 更加简单。不过如果想搜索“12:34:56”这样的时间单位,用正则表达式就方便得多。

str = "12:34:56";
if (str.match(/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9]$/) {
    alert("匹配");
}

RegExp() 的 flag 部分可以指定 "i"、"g"、"m" 。也可以像 "ig" 这样一起指定。详细内容请看下一节。

regexp.ignoreCase
regexp.global
regexp.source

ignoreCase 返回有没有指定 i选项 的布尔值(就是上面match括号里 /.../ 的后面有没有加 i)。global 返回有没有指定 g选项 的布尔值。source 则返回正则表达式部分的字符串(就是上面match括号里 /.../ 的内容)。

re = new RegExp("DEF", "ig");
document.write(re.ignoreCase + "<br>");   // → true
document.write(re.global + "<br>");       // → true
document.write(re.source + "<br>");       // → DEF
RegExp.$

RegExp.$ 的形式与意义如下。

形式 意义
RegExp.$nn 个括号里的字符串。详细内容见后文。
RegExp.$&等同于 RegExp.lastMatch 。
RegExp.$`等同于 RegExp.leftContext 。
RegExp.$"等同于 RegExp.rightContext 。
RegExp.$+等同于 RegExp.lastParen 。
RegExp.$_等同于 RegExp.input 。
RegExp.$*等同于 RegExp.multiline 。

■ 正则表达式语法

正则表达式可以用下面的形式来进行匹配。

正则表达式 意义
A字符A
ABC字符串ABC
[ABC]A、B、C其中一个字符
[A-C]从A到C的其中一个字符
[^ABC]不是A、B、C的任意一个字符
.任意一个字符
A*匹配前面的子表达式零次或多次。例如,"AP*" 能匹配 "A" 以及 "APP"。 * 等价于{0,}。
A+匹配前面的子表达式一次或多次。例如,"AP+" 能匹配 "AP" 以及 "APP",但不能匹配 "A"。+ 等价于 {1,}。
A?匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。
^A以A开始的字符串
A$以A结束的字符串
ABC|DEF|GHIABC或DEF或GHI
A{2}2个A(AA)
A{2,}2个以上A(AA、AAA、AAAA、...)
A{2,3}2个~3个A(AA、AAA)
[\b]退格

反斜杠(\)后面的字符有特殊的意思。

形式 意义
\b空格等单词的分隔
\B\b以外的字符
\cACtrl-A
\d任意数值(等同于 [0-9])
\D数值以外的字符(等同于[^0-9])
\f换页符
\n换行符
\r回车
\s一个字符的分隔符([ \f\n\r\t\v])
\S\s以外的一个字符
\t制表符(TAB符)
\v垂直制表符
\w英文字母和数字(等同于 [A-Za-z0-9_])
\W\w以外的字符
\2匹配第2个 (...) 的字符串
\o0338进制数033的字符
\x1b16进制数1b的字符
\其他其他字符自身

RegExp() 的第2个参数,或是写在 /.../ 后面的 i、g、m 的意义如下。

选项 意义
i不区分大小写
g全文匹配(不光匹配第一个)
m搜索复数行

指定 i 选项则不区分大小写。

if ("abc".match(/ABC/)) { alert("匹配"); }    // 不匹配
if ("abc".match(/ABC/i)) { alert("匹配"); }   // 匹配

指定 g 选项则全文匹配。返回匹配字符串的数组。

xx = "12:34:56".match(/\d+/g);
document.write(xx.length + "<br>); // → 3
document.write(xx[0] + "<br>); // → "12"
document.write(xx[1] + "<br>); // → "34"
document.write(xx[2] + "<br>); // → "56"

指定 m 选项则执行复数行匹配。行头符(^)和行末符($)不光匹配字符串的开头和结尾,还匹配各行的开头和结尾。

str = "123\n456\n789";                       // \n 是换行
if (str.match(/^456/)) { alert("匹配"); }    // 不匹配
if (str.match(/^456/m)) { alert("匹配"); }   // 匹配

在正则表达式里使用了 (...) 的话,之后可以把 (...) 对应的部分取出来。

xx = "12:34:56".match(/(\d+):(\d+):(\d+)/);
document.write(RegExp.$1 + "<br>"); // → 12
document.write(RegExp.$2 + "<br>"); // → 34
document.write(RegExp.$3 + "<br>"); // → 56

■ 匹配

regexp.exec([str])
str.match(regexp)

执行匹配,返回匹配部分的字符串(指定 g 选项时返回数组)。exec() 里省略 str 的时候,会用在 RegExp.input 里指定的字符串进行匹配。

re = new RegExp("[0-9]+");
document.write(re.exec("abc123") + "<br>");         // → 123
document.write("abc123".match(re) + "<br>");        // → 123
document.write("abc123".match(/[0-9]+/) + "<br>");  // → 123
regexp.compile(patern[, flag])

把正则表达式预先编译为内部表达式以提高匹配的速度。(个人感觉没什么区别)

re = new RegExp("");
re.compile("[0-9]+");
for (i = 0; i < 1000; i++) {
    if (str.match(re)) {
        :
    }
}
RegExp.input

把匹配字符串传递给 exec() 。等同与 $_ 。

re = new RegExp("[0-9]+");
RegExp.input = "abc123";
document.write(RegExp.exec() + "<br>");
RegExp.input = "xyz456";
document.write(RegExp.exec() + "<br>");
RegExp.multiline

设定为 true 的话效果跟 m 选项一样执行复数行匹配。等同与 $* 。

RegExp.multiline = false;
document.write("123\n456\n789".match(/^456/) + "<br>");
RegExp.multiline = true;
document.write("123\n456\n789".match(/^456/) + "<br>");

■ 匹配结果

RegExp.$n

返回之前执行的正则表达式匹配中的第 n 个 (...) 对应的字符串。

"12:34:56".match(/(\d+):(\d+):(\d+)/);
document.write(RegExp.$1 + "<br>");   // → 12
document.write(RegExp.$2 + "<br>");   // → 34
document.write(RegExp.$3 + "<br>");   // → 56
RegExp.index
RegExp.lastIndex

index 是匹配到的字符串的起始位置,lastIndex 是匹配到的字符串的后面一个字符的位置。开始的字符的位置为 0 。

re = new RegExp("123");
"abc123def".match(re);
document.write(RegExp.index);     // → 3
document.write(RegExp.lastIndex); // → 6
RegExp.lastMatch
RegExp.leftContext
RegExp.rightContext
RegExp.lastParen

返回之前执行的字符串匹配中的,最后匹配到的字符串(lastMatch)、匹配到的字符串的左边的字符串(leftContext)、匹配到的字符串的右边的字符串(rightContext),以及最后的 (...) 所对应的字符串(lastParen)。它们分别等同于 $&、$`、$'、$+ 。

"abc123def".match(/(123)/);
document.write(RegExp.lastMatch + "<br>");    // → 123
document.write(RegExp.leftContext + "<br>");  // → abc
document.write(RegExp.rightContext + "<br>"); // → def
document.write(RegExp.lastParen + "<br>");    // → 123