概述

JavaScript 实现了正则表达式(简称 regex)用于在字符串中搜索匹配项。与其他脚本语言一样,它允许超越简单的逐字匹配,甚至可以用于解析特定格式的字符串。

与字符串不同,正则表达式由斜杠(/)字符定界,并且可能附带一些选项。

正则表达式最常见的用途是与 string.match()string.replace() 方法结合使用。

举例说明:

strArray = "Hello world!".match(/world/); // 单元素数组;注意斜杠
strArray = "Hello!".match(/l/g); // 匹配的字符串返回一个字符串数组
"abc".match(/a(b)c/)[1] === "b" // 匹配的子组是结果数组的第 2 项(索引 1)
str1 = "Hey there".replace(/Hey/g, "Hello");
str2 = "N/A".replace(/\//g, ","); // 斜杠需要转义
str3 = "Hello".replace(/l/g, "m").replace(/H/g, "L").replace(/o/g, "a"); // 多重替换
if (str3.match(/emma/)) { console.log("Yes"); }
if (str3.match("emma")) { console.log("Yes"); } // 引号也可以使用
"abbc".replace(/(.)\1/g, "$1") === "abc" // 反向引用

兼容性

JavaScript 的正则表达式集合遵循扩展集。尽管从 JavaScript 复制正则表达式模式到其他地方通常可以按预期工作,但某些旧程序可能无法按预期执行。

在搜索表达式中,\1 用于反向引用已匹配的分组,与其他实现相同。 在替换字符串中,$1 替代了搜索中的匹配分组,而不是使用 \1

示例:

"abbc".replace(/(.)\1/g, "$1") => "abc"
符号 作用
` `
( 魔法字符,\( 是字面量
(?=...)(?!...)(?<=...)(?<!...) 不可用  

示例

匹配

string = "Hello world!".match(/world/);
stringArray = "Hello world!".match(/l/g); // 匹配的字符串返回一个字符串数组
"abc".match(/a(b)c/)[1] => "b" // 匹配的子组是结果数组的第 2 项(索引 1)

替换

string = string.replace(/expression without quotation marks/g, "replacement");
string = string.replace(/escape the slash in this\/way/g, "replacement");
string = string.replace( ... ).replace ( ... ).replace( ... );

测试

if (string.match(/regexp without quotation marks/)) {
  // do something
}

修饰符

单字母修饰符:

  • g:全局搜索。返回匹配项的列表(数组)。
  • i:忽略大小写搜索。
  • m:多行匹配。如果操作数字符串包含多行,^$ 匹配每行的开头和结尾,而不仅仅是整个字符串的开头和结尾:
    "a\nb\nc".replace(/^b$/g, "d") === "a\nb\nc"
    "a\nb\nc".replace(/^b$/gm, "d") === "a\nd\nc"
    

运算符

运算符 作用
\b 匹配单词的边界
\w 匹配字母数字字符,包括 _
\W 否定 \w
\s 匹配空白字符(空格、制表符、换行符、换页符)
\S 否定 \s
\d 匹配数字
\D 否定 \d

函数调用

对于复杂操作,可以使用函数处理匹配到的子字符串。以下代码演示了如何将每个单词的首字母大写。因为每个要大写的字母是不同的字符,所以不能通过简单的替换来实现:

var capitalize = function(matchobj) {
  var group1 = matchobj.replace(/^(\W)[a-zA-Z]+$/g, "$1");
  var group2 = matchobj.replace(/^\W([a-zA-Z])[a-zA-Z]+$/g, "$1");
  var group3 = matchobj.replace(/^\W[a-zA-Z]([a-zA-Z]+)$/g, "$1");
  return group1 + group2.toUpperCase() + group3;
};

var classicText = "To be or not to be?";

var changedClassicText = classicText.replace(/\W[a-zA-Z]+/g, capitalize);

console.log(changedClassicText === "To Be Or Not To Be?");

此函数会对每个匹配的子字符串调用。函数签名如下:

function (''<matchedSubstring>[, <capture1>, ...<captureN>, <indexInText>, <entireText>]'') {
  ...
  return ''<stringThatWillReplaceInText>'';
}
  • 第一个参数是匹配的子字符串。
  • 随后的参数是子字符串中的捕获分组。捕获有多少个参数就有多少个参数。
  • 接下来的参数是该子字符串在文本中的起始索引。
  • 最后一个参数是整个文本的剩余部分。
  • 返回值将替换文本中的匹配子字符串。

参考资料

Last modified: Monday, 13 January 2025, 3:03 PM