JavaScript 正则表达式

JavaScript 正则表达式是一个内置的对象,是用于匹配文本中字符组合的模式。正在表达式对搜索文本、验证文本、替换文本很有帮助,也很方便。

JavaScript 正则表达式是一个内置的对象,是用于匹配文本中字符组合的模式。正在表达式对搜索文本、验证文本、替换文本很有帮助,也很方便。

正则表达式创建了一种字符序列的模式,可以匹配很多符合此模式的字符串,比如 .* 可以匹配到任意数量的任意字符串。

正则表达式经常用在以下场景:

  • 表单输入内容的验证
  • 文本模式搜索
  • 文本批量替换

正则表达式语法

有两种方法构建一个正则表达式:

  1. 使用正则表达式字面量(由包含在两个斜杠 / 之间的模式组成):

    /pattern/flags
    
  2. 调用 RegExp 对象的构造函数:

    new RegExp("pattern", "flags");
    

无论是那种方法创建正砸表达式,flags 都是可选的。

示例:

/Hello\s+World/i;

说明:

  • 两个 / 包含的内容是正则表达式的字符串模式 Hello\s+World
  • Hello\s+World 这个模式表示 Hello World 字符串,其中 HelloWorld 中间至少有一个空格。
  • \s 是正则表达式内置的一个符号,表示空白符号,比如空格,制表符等。
  • i 是一个标记,表示匹配的时候不区分大小写。也就是 Hello WorldHELLO WORLD 都是符合这个模式的。

正则表达式模式

什么是模式? 我们一般称具有相同规则的一类事物具有相同的模式。简单的举例:

  • 这是一组数字
  • 这是一组字母
  • 这是电子邮箱的命名规则

正则表达式定义了一些字符表示字符串的模式,包括:

字符 说明
. 默认匹配除换行符之外的任何单个字符。
x|y 匹配字符 x 或者字符 y
[xyz] 匹配 x y z 中的任意一个字符
[a-z] 匹配任意一个小写字母。
[A-Z] 匹配任意一个小写字母。
[0-9] 匹配任意一个数字。
* 匹配数量。匹配 0 次或多次前一个表达式,相当于 {0,}
+ 匹配数量。匹配 1 次或者多次前一个表达式,相当于 {1,}
? 匹配数量。匹配 0 次或者 1 次前一个表达式,相当于 {0,1}
{n} 匹配数量。n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。
{n,} 匹配数量。n 是一个正整数,匹配前一个字符至少出现了 n 次。
{n,m} 匹配数量。n 和 m 都是正整数。匹配前面的字符至少 n 次,最多 m 次。如果 n 或者 m 的值是 0, 这个值被忽略。
^ 默认匹配行的开始。多行模式下也匹配换行符后紧跟的位置。
$ 默认匹配行的结束。多行模式下也匹配换行符前的位置。
\ 转义字符
\s 匹配一个空白字符,包括空格、制表符、换页符和换行符。
\S 匹配一个非空白字符。
\d 匹配一个数字,相当于 [0-9]
\D 匹配一个非数字字符,相当于 [^0-9]
\w 匹配一个单字字符(字母、数字或者下划线),相当于 [A-Za-z0-9_]
\W 匹配一个非单字字符,相当于 [^a-za-z0-9_]
\b 匹配一个词的边界。
\B 匹配一个非单词边界。
\t 匹配一个水平制表符 (U+0009)。
\n 匹配一个换行符 (U+000A)。
\r 匹配一个回车符 (U+000D)。

正则表达式标志

正则表达式定义了 6 个标志(flags)进行高级搜索,比如:全局模式、不区分大小写等。

标志 说明
i 不区分大小写搜索。
g 全局搜索。全局搜索会匹配所有的项目而不是只匹配一次
m 多行搜索。
s 允许 . 匹配换行符。
u 使用 unicode 码的模式进行匹配。
y 执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

这些标志参数既可以单独使用也能以任意顺序一起使用, 并且被包含在正则表达式实例中。比如:

let regex1 = /[a-z]/i; // 不区分大小写搜索字母
let regex2 = /[a-z]/gi; // 不区分大小写全局搜索字母
let regex3 = /[a-z]/gim; // c

使用字符串方法

在 JavaScript 的字符串中有两个方法可以使用正则表达式: search()replace()

search() 方法使用表达式来搜索匹配项,并返回匹配项的位置。

replace() 方法根据指定的表达式搜索字符串,并用指定的内容进行替换。

String.search()

search() 方法的参数可以是普通字符串,也可以是正则表达式。

search() 方法在字符串中搜索指定值并返回匹配的位置:

在字符串中搜索 “GoBeta.net”:

let text = "Visit GoBeta.net!";
let n = text.search("GoBeta.net"); // n 为 6

使用正则表达式进行不区分大小写的搜索 “gobeta.net” :

let text = "Visit GoBeta.net";
let n = text.search(/gobeta.net/i); // n 为 6

String.replace()

replace() 方法的第一个参数可以是普通字符串,也可以是正则表达式。

replace() 方法用指定值替换查找的字符串:

let text = "Visit Microsoft!";
let result = text.replace("Microsoft", "GoBeta.net");

使用正则表达式不区分大小写查找 Microsoft, 并替换为 GoBeta.net:

let text = "Visit Microsoft!";
let result = text.replace(/microsoft/i, "GoBeta.net");

result 的结果将是:Visit GoBeta.net!

你注意到了吗?

可以在上述方法中使用正则表达式参数(而不是字符串参数)。 正则表达式可以使您的搜索更加强大(例如不区分大小写)。

使用 RegExp 对象的方法

在 JavaScript 中,RegExp 对象是一个具有预定义属性和方法的正则表达式对象。

test()

test() 方法用于测试正则表达式与指定的字符串是否匹配,匹配则返回 true,否则返回 false。

以下示例在字符串中搜索字符“e”:

const pattern = /e/;
pattern.test("The best things in life are free!");

由于字符串有字母 “e”,上面代码的输出是:true

exec()

exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。

以下示例在字符串中搜索字符“e”:

/e/.exec("The best things in life are free!");

在设置了 global 或 sticky 标志位的情况下(如 /foo/g/foo/y),JavaScript RegExp 对象是有状态的。他们会将上次成功匹配后的位置记录在 lastIndex 属性中。使用此特性,exec() 可用来对单个字符串中的多次匹配结果进行逐条的遍历(包括捕获到的匹配),而相比之下, String.prototype.match() 只会返回匹配到的结果。

如下面的例子,通过正则匹配出不区分大小写 ab 后跟一个数字的所有子串:

const regex = /ab\d/gi;
const str = "abi ab1 Ab2 abc ABD AB3 aBb";
let result;

while ((result = regex.exec(str)) !== null) {
  console.log(result);
}

输出应是:

Array [ "ab1" ]
Array [ "Ab2" ]
Array [ "AB3" ]