JavaScript 的正则表达式

一、基本使用 在 JavaScript 中,可以用下面的两种方法来创建一个正则表达式(RegExp)对象:var re = fox ; var re = n

一、基本使用

在 JavaScript 中,可以用下面的两种方法来创建一个正则表达式(RegExp)对象:

var re = /fox/;
var re = new RegExp("fox");

创建了 RegExp 对象后,就可以用 test() 方法来检测某个字符串是否匹配。例如:

var re = /fox/;
var str = "The quick brown fox jumps over the lazy dog";
alert(re.test(str)); // true 

test() 方法根据字符串是否匹配该正则表达式,返回 true 或者 false。

RegExp 对象还有另一个参数,用于指明匹配标志。该参数是字母 g, i 和 m 的任意组合。其中 g 表示全局模式,即查找全部匹配的子串;i 表示不区分大小写;m 表示多行模式,即让 ^ 和 $ 符也分别匹配行首和行尾(见下面的介绍)。例如

var re = /fox/gi;
var re = new RegExp("fox", "gi");

二、选择符 |

如果我们要匹配 cat 或者 dog,可以用选择符 |。例如:

var re = /cat|dog/;
var str = "The quick brown fox jumps over the lazy dog";
alert(re.test(str)); // true 

三、字符集 [] 

如果我们需要匹配某些字符,可以用字符集符号 []。比如 [aeiou] 匹配 5 种元音字母。再如下面的例子:

var re = /f[aeiou]x/;
var str = "The quick brown fox jumps over the lazy dog";
alert(re.test(str)); // true

由于字符串中包含 fox,所以匹配成功。如果我们需要匹配小写字母,不用一一列出,用 [a-z] 这种简写方式就可以了。类似地,[0-9] 匹配10个数字符号。相反地,如果要匹配非元音字母,可以用 [^aeiou]。方括号内部最前面的 ^ 符号表示补集。

同时,对常用的字符集,我们也有下面这些简记方式:

\0 匹配 NUL 字符
\b 匹配位于单词的开头或结尾的位置
\B 匹配不处在单词的开头或结尾的位置
\d 匹配数字字符,等同于 [0-9]
\D 匹配非数字字符,等同于 [^0-9]
\f 匹配换页符
\n 匹配换行符
\r 匹配回车符
\s 匹配 Unicode 空白字符,即 [\f\n\r\t\v \u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u205f\u3000\ufeff]
\S 匹配非 Unicode 空白字符,即 [^\f\n\r\t\v \u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u205f\u3000\ufeff]
\t 匹配制表符
\v 匹配垂直制表符
\w 匹配单词字符,等同于 [a-zA-Z0-9_]
\W 匹配非单词字符,等同于 [^a-zA-Z0-9_]
. 匹配单个字符,除了换行符和 Unicode 行终止符,即 [^\n\r\u2028\u2029]

其中 \s \S . 这几个字符集,可能不同的浏览器的实现不一样。

四、重复符 ? * +

如果需要匹配某些重复的字符,可以在该字符后面加上重复符 ?*+。其中 ? 表示重复 0 次或 1 次,* 表示重复 0 次或多次,+ 表示重复 1 次或多次。例如:

var re1 = /9?/;
var re2 = /9*/;
var re3 = /9+/;
var str = "The quick brown fox jumps over the lazy dog";
alert(re1.test(str)); // true
alert(re2.test(str)); // true
alert(re3.test(str)); // false

类似地,{2,} 表示匹配 2 次或以上,而 {2,5} 表示匹配至少 2 次而且至多 5 次。

五、非贪婪匹配

前面的 * 和 ? 的贪婪匹配的重复符,而 *? 和 +? 是对应的非贪婪匹配的重复符。贪婪匹配将得到最长的匹配,而非贪婪匹配将得到最短的匹配。例如:

/-.+-/.exec("-ab-cd-e")    // -ab-cd-
/-.+?-/.exec("-ab-cd-e")   // -ab-  

六、字符串开头和结束

使用 ^$,可以分别匹配字符串开头和结束的位置。例如:/^[1-9]\d*$/ 匹配一个正整数。如果该正则表达式有 m 标志,则它们也可以分别匹配行首和行尾。此时,字符串的各行由 \r\n 分割。

七、捕获组和非捕获组

(x) 包含的内容为一个捕获组,而用 (?:x) 包含的内容为一个非捕获组。捕获组的内容将出现在 re.exec(str)str.search(re) 函数的返回值里面。另外,我们可以用 \1\2 分别引用前面的第 1 个,第 2 个捕获组的内容,等。这些捕获组按照左括号出现的顺序编号。

八、向前查找

x(?=y) 表示当 x 在 y 之前时匹配 x,而 x(?!y) 当 x 不在 y 之前时匹配 x。对这两种情形,y 都不包含在匹配的字符串中。例如:

/-\w+(?!-)/.exec("a-bcd-") // 'bc'

九、特殊字符

在正则表达式中,( ) [ ] { } \ ^ $ . | ? * + 这 14 个字符是特殊字符,要匹配这些字符,必须在它们前面用反斜杠 \ 进行转义。

十、相关函数列表

与正则表达式相关的函数主要在 RegExp 对象和 String 对象中,包括下面这些函数。

re.test(str) 和 str.search(re):判断字符串和正则表达式是否匹配,前者返回值为 true 或者 false,后者返回值为匹配子串的起始位置。

re.exec(str) 和 str.match(re): 查找字符串中和正则表达式匹配的子字符串。

如果正则表达式中没有 g 标志,两者的返回值是一样的:匹配成功返回值为数组,这个数组的第一项为所匹配的子字符串,后面各项为各个捕获组的内容;返回的数组中还包含两个属性 index 和 input,分别表示所匹配的位置和输入字符串;匹配失败返回值为 null。

如果正则表达式中有 g 标志,两者的返回值不一样:前者的返回值和不含 g 标志时类似,但此时正则表达式 re 中多了一个 lastIndex 属性,指明下次搜索的开始位置,如果匹配不成功则 lastIndex 属性被重置为 0。而后者的返回值包含所有匹配的子字符串,而且不再有 index 和 input 属性。

如果我们需要得到所有匹配的字符串的位置,只能用 re.exec(str)。例如:

var re = /(\n|\r\n){2,}/g;
var str = "ab\n\ncd\n\n\nef";
var result, i = 0, msg;
while ((result = re.exec(str)) !== null) {
  msg = "Found a paragraph at " + i + '-' + result.index + ". ";
  msg += "Next match starts at " + re.lastIndex; 
  console.log(msg);
  i = re.lastIndex;
}
if (i < str.length) {
  console.log("Found a paragraph at " + i + '-' + str.length + ".");
}
// Found a paragraph at 0-2. Next match starts at 4
// Found a paragraph at 4-6. Next match starts at 9
// Found a paragraph at 9-11.

str.replace(re, newstr):将 str 中与正则表达式匹配的子字符串替换为 newstr。默认只替换一次,如果要替换多次需要在正则表达式中加上 g 标志。例如:

var str = 'one apple and two apples';
var re1 = /apple/, re2 = /apple/g;
var newstr = 'banana';
console.log(str.replace(re1, newstr));
// one banana and two apples
console.log(str.replace(re2, newstr));
// one banana and two bananas

另外,在 replace 的第二个参数 newstr 中,$ 字符有如下特殊含义(因此 newstr 包含 $ 时需要小心):

  • $& :表示所匹配的子字符串
  • $`:表示所匹配的子字符串之前的字符串
  • $' :表示所匹配的子字符串之后的字符串
  • $n 或 $nn:表示第 n 或 nn 个捕获组的内容
  • $$ :表示字符 $

这个 replace 方法的第二个参数也可以是一个函数,即 str.replace(re, func)。此时替换函数 func 的参数中,第一个为所匹配的子字符串,接下来为各个捕获组的内容;接下来是匹配子串的起始位置,最后一个参数是所查找的字符串。该替换函数的返回值将作为替换的内容。例如:

text.replace(/[<>\&\"\']/g, function(c) {
    return '&#' + c.charCodeAt(0) + ';';
});

这个例子中,我们将 HTML 的预留字符替换成它的字符实体。

参考资料:

[1] RegExp - JavaScript | MDN
[2] test - JavaScript | MDN
[3] exec - JavaScript | MDN
[4] String.match - JavaScript | MDN
[5] search - JavaScript | MDN
[6] replace - JavaScript | MDN
[7] JavaScript RegExp 对象参考手册
[8] Online RegExp Tester (1) (2)
[9] javascript之正则表达式 (一) (二)
[A] 深入浅出之正则表达式 (一) (二)
[B] JavaScript, Regex, and Unicode
[C] JavaScript Regex and Unicode Tests

[YAML] Updated: 2014-01-12 10:23:00

您可能有感兴趣的文章
微信小程序列表中item左滑删除功能

小程序视频列表中视频的播放与停止的示例代码

从对象列表中获取一个对象的方法,依据关键字和值

jQuery初级好代码教程之网站品牌列表效果

JS仿QQ好友列表展开、收缩功能(第一篇)