正则表达式是一种用单一模式表达与指定条件匹配的多个字符串的方法。正则表达式也是 JavaScript 中的对象。在本节中,我们将解释如何在 JavaScript 中使用正则表达式。
目录
18-1 创建正则表达式对象
18-2 正则表达式中的转义处理
18-3 测试字符串是否匹配正则表达式
18-4 获取字符串匹配正则表达式(RegExp.prototype.exec)
18-5 获取匹配正则表达式的字符串索引(String.prototype.search)
18-6 获取匹配正则表达式的所有字符串(String.prototype.match)
18-7 使用正则表达式(String.prototype.split)按分隔符拆分字符串
18-8 用新字符串替换与正则表达式匹配的字符串 (String.prototype.replace)
首先,我将向您展示如何创建一个正则表达式对象,然后我将向您展示如何使用 JavaScript 的 RegExp 和 String 对象提供的正则表达式方法。解释正则表达式和字符串是否匹配,如果匹配,匹配的部分,以及如何使用正则表达式替换字符串。
之后,我将向您展示如何使用元字符创建正则表达式模式,以及 JavaScript 正则表达式中可用的标志类型。
要在 JavaScript 中使用正则表达式,请创建一个表示正则表达式模式的正则表达式对象。正则表达式对象可以写成正则表达式文字或使用 RegExp 对象的构造函数。本节介绍如何在 JavaScript 中创建正则表达式对象。
使用正则表达式文字
正则表达式对象是正则表达式中使用的模式的定义。首先是如何使用正则表达式文字创建正则表达式对象。格式如下。
/图案/
/图案/标志
将表示正则表达式模式的值括在斜杠 (/) 中。如果你想设置一个标志,把它写在斜杠后面(标志在另一页上解释)。
看看下面的示例。
let regexp1 = /apple/;
let regexp2 = /[a-zA-Z]{4}/;
第一个正则表达式对象是匹配“apple”的模式。如果目标字符串包含与“apple”相同的字符串,则此正则表达式匹配。不匹配正则表达式。
第二个正则表达式对象是使用具有特殊含义的元字符编写的模式,用于匹配由字母组成的四字符字符串。例如,’Desk’ 和 ‘good’ 将匹配此正则表达式,但具有不同字符数的 ‘cat’ 和 ‘Apple’ 以及使用非字母字符的 ‘1024’ 将不会匹配正则表达式表达。
正则表达式的特点是能够使用各种元字符创建模式。我将在另一页上解释如何使用元字符。
设置标志时,写一个或多个代表标志的值。
let regexp1 = /[a-z]{4}/i;
let regexp2 = /[a-z]{4}/im;
第一个正则表达式对象设置了 i 标志,第二个正则表达式对象设置了 i 和 g 标志。
使用 RegExp 构造函数
以下是使用 RegExp 对象的构造函数创建正则表达式对象的方法:格式如下。
新的正则表达式(模式[,标志])
第一个参数是正则表达式文字或表示模式的字符串值。要设置标志,请在第二个参数中将一个或多个标志作为字符串写入。
看看下面的示例。
let regexp1 = new RegExp(/lemon/);
let regexp2 = new RegExp('lemon');
两者都创建相同的正则表达式对象。请注意,将模式指定为字符串时,无需将模式括在斜杠 (/) 中。
要设置标志,请编写:
let regexp1 = new RegExp(/lemon/, 'i');
let regexp2 = new RegExp('lemon', 'ig');
如果正则表达式的模式已经确定,我认为使用正则表达式字面量来创建正则表达式对象基本上是简单易懂的。如果您不知道模式,请使用 RegExp 构造函数,它允许您将模式指定为字符串。
现在让我们实际创建一个正则表达式对象并检查目标字符串是否与正则表达式匹配。
let regexp1 = /movie/;
let regexp2 = /driving/;
let str = 'I like movies and sports'
console.log(regexp1.test(str));
>> true
console.log(regexp2.test(str));
>> false
RegExp 对象的实例方法 test 检查一个字符串是否匹配一个正则表达式并返回一个布尔值。
我创建了两个正则表达式对象并检查目标字符串是否与每个正则表达式对象匹配。目标字符串包含“movie”,所以第一个正则表达式匹配,但目标字符串不包含“driving”,所以第二个正则表达式不匹配。我做到了。
JavaScript 中的正则表达式在编写模式时具有特殊字符,例如“.”和“*”。如果要将此类字符视为单个字符而不是具有特殊含义的字符,则需要使用反斜杠 () 对它们进行转义。还有其他需要注意的事情,例如使用正则表达式文字时的正斜杠,以及在 RegExp 构造函数中使用字符串编写模式时。在这里,我们将解释在正则表达式中编写模式时的转义过程。
转义具有特殊含义的字符
正则表达式模式中使用的某些字符具有特殊含义,例如点 (.) 和加号 (+)。这些被称为元字符。例如,让我们看一下这样的正则表达式文字:
let regexp = /a.b/;
如果按字面解释,此模式似乎与三个连续字符“a”、“.”和“b”组成的任何字符串相匹配。如果您实际使用 RegExp 对象的测试方法来查看字符串是否与正则表达式匹配,您将得到如下结果:
看看下面的示例。
let regexp = /a.b/;
console.log(regexp.test('oa.bo'));
>> true
console.log(regexp.test('oaxbo'));
>> true
第一个 ‘oa.bo’ 在字符串中包含字符串 ab,所以我知道它会匹配,但第二个 ‘oaxbo’ 在字符串中包含字符串 ab。即使不是,也已匹配。
这是因为如果在模式中写一个点 (.),它具有匹配任何单个字符的特殊含义。所以 /ab/ 不仅可以匹配 ‘ab’,还可以匹配以 ‘a’ 开头,以 ‘b’ 结尾的三字符字符串,例如 ‘axb’ 和 ‘aYb’。
如您所见,正则表达式中的某些字符在模式中使用时具有特殊含义。如果要匹配这样一个字符作为简单字符而不是具有特殊含义的字符,则在字符前写一个反斜杠(\)以将其转义。(Windows 环境使用反斜杠代替反斜杠)。
对于前面的模式,写 /a\.b/ 而不是 /ab/ 将只匹配三个字符“a”、“.”和“b”连续的字符串。看看下面的示例。
let regexp = /a\.b/;
console.log(regexp.test('oa.bo'));
>> true
console.log(regexp.test('oaxbo'));
>> false
第一个 ‘oa.bo’ 匹配,因为它包含字符串 ab,但第二个 ‘oaxbo’ 不包含字符串 ab。因此它不再匹配。如果您想将其视为单个字符而不是像这样的特殊字符,请使用反斜杠对其进行转义。
用于转义的反斜杠(\)也有特殊的含义,所以如果要将反斜杠本身作为单个字符来匹配,请同样用反斜杠写成’\\’。
let regexp = /\\/;
使用正则表达式字面量创建正则表达式对象时,由于正则表达式字面量是用斜杠(/)包围起来的,所以在模式中写斜杠时需要转义。
/图案/
例如,当使用正则表达式文字编写 a/b 这样的模式时,按原样编写将导致错误。
let regexp = /a/b/;
>> SyntaxError: Invalid regular expression flags
在斜杠前写一个反斜杠(\)用于转义。
let regexp = /a\/b/;
使用 RegExp 构造函数(将模式指定为字符串)创建正则表达式对象时,斜杠没有特殊含义,不需要转义。
let regexp = new RegExp('a/b');
何时使用 RegExp 对象构造函数
使用 RegExp 构造函数创建正则表达式对象时,将模式指定为字符串时必须小心。
new RegExp('图案');
反斜杠是一个字符,作为JavaScript字符串中对字符进行转义的字符,具有特殊含义,因此需要对反斜杠(\)进行转义。
例如,如果您在图案中写入 \d,则表示匹配数字 0 到 9 的特殊字符,而不是反斜杠 + d。在字符串中写入类似 \d 的模式时,在反斜杠(字符串)转义处理之前写入反斜杠。
let regexp = new RegExp('\\d');
请注意,在将正则表达式对象创建为正则表达式文字时,不需要将反斜杠转义为字符串。
let regexp = /\d/;
RegExp对象的实例方法test测试目标字符串是否匹配正则表达式,返回true或false。这里我们将解释如何使用 RegExp 对象的测试方法。
test如何使用测试方法
RegExp 对象的测试方法测试目标字符串是否匹配正则表达式并返回布尔结果。格式如下。
正则表达式 object.test(string)
如果参数中指定的字符串至少匹配一个正则表达式,则返回 true。如果没有匹配项,则返回 false。
看看下面的示例。
let regexp = /ball/;
let str1 = 'Go to see a baseball game';
let str2 = 'Make a cake tomorrow';
console.log(regexp.test(str1));
>> true
console.log(regexp.test(str2));
>> false
正则表达式是匹配“ball”的模式。第一个字符串包含“ball”,因此它与正则表达式匹配。所以测试方法将返回 true。
Go to see a baseball game
第二个字符串不包含“ball”,因此它与正则表达式不匹配。所以测试方法将返回 false。
请看另一个例子。
let regexp = /a.e/;
let str1 = 'Go to see a baseball game';
let str2 = 'Make a cake tomorrow';
console.log(regexp.test(str1));
>> true
console.log(regexp.test(str2));
>> true
模式中的点 (.) 具有特殊含义并匹配任何单个字符。因此,我们的正则表达式是一种模式,可以匹配以“a”开头后跟任何单个字符并以“e”结尾的任何字符串。测试方法都返回 true,因为第一个字符串和第二个字符串都匹配正则表达式:
Go to see a baseball game
Make a cake tomorrow
如果设置了全局标志
可以通过在模式末尾写入 g 来设置全局标志。
/图案/g
如果正则表达式设置了全局标志,那么当您运行测试方法并且字符串与正则表达式匹配时,正则表达式对象的 lastIndex 属性的值将设置为匹配字符串中下一个字符的索引. (如果未设置全局标志,即使测试方法匹配,lastIndex 仍将为 0)。
let regexp = /ball/g;
let str = 'baseball and football';
console.log(regexp.test(str));
>> true
console.log(regexp.lastIndex);
>> 8
之后,如果以相同的字符串作为同一个正则表达式的参数执行测试方法,它会从当前 lastIndex 指示的字符串位置开始测试该字符串是否与正则表达式匹配。如果再次匹配,将再次更新 lastIndex 属性的值。
let regexp = /ball/g;
let str = 'baseball and football';
console.log(regexp.test(str));
>> true
console.log(regexp.lastIndex);
>> 8
console.log(regexp.test(str));
>> true
console.log(regexp.lastIndex);
>> 21
如果执行测试方法时正则表达式不匹配,lastIndex会返回0。
如果目标字符串与正则表达式匹配,则 RegExp 对象的实例方法 exec 检索字符串的匹配部分。另外,如果正则表达式模式中包含捕获组,则也获取匹配该捕获组的字符串。这里我们将解释如何使用 RegExp 对象的 exec 方法。
如何使用exec方法
如果目标字符串与正则表达式匹配,则 RegExp 对象的 exec 方法会检索匹配的字符串。格式如下。
正则表达式 object.exec(string)
如果参数中指定的字符串与正则表达式匹配,则返回包含匹配字符串的数组。如果没有匹配项,则返回 null。在返回值数组中,索引为 0 的元素包含匹配整个模式的字符串,索引 1 之后的元素包含匹配 set 捕获组所包围的模式的字符串。(如果您没有设置捕获组,则索引 1 之后没有元素)。
数组[0] 匹配整个模式的字符串
数组[1] 匹配捕获组1的字符串
数组[2] 匹配捕获组2的字符串
・・・
数组[n] 匹配捕获组n的字符串
看看下面的示例。对于首先不包含捕获组的模式。
let regexp = /20\d{2}-\d{2}-\d{2}/;
let result1 = regexp.exec('Today is 2022-09-15');
console.log(result1[0]);
>> 2022-09-15
let result2 = regexp.exec('Yesterday is 1998-12-07');
console.log(result2[0]);
>> TypeError: Cannot read property '0' of null
如果字符串与正则表达式匹配,您将收到一个数组,其中包含与整个模式匹配的字符串作为索引 0 处元素的值。但是,如果没有匹配项,返回值将为 null,并且尝试获取索引为 0 的元素而不是 null 将引发 TypeError。添加条件分支是否为null或处理异常如下。
let regexp = /20\d{2}-\d{2}-\d{2}/;
let result = regexp.exec('Yesterday is 1998-12-07');
if (result !== null){
console.log(result[0]);
}else{
console.log('Not Match');
}
>> Not Match
如果模式包含捕获组
那么如果模式包含一个捕获组。要创建捕获组,请将模式括在括号 () 中。然后就可以得到与捕获组中设置的模式部分相匹配的字符串。
请看下面的示例。
let regexp = /(20\d{2})-(\d{2})-(\d{2})/;
let result = regexp.exec('Today is 2020-08-14');
for (let i = 0 ; i < result.length ; i++){
console.log('i=' + i + ', match=' + result[i]);
}
>> i=0, match=2020-08-14
>> i=1, match=2020
>> i=2, match=08
>> i=3, match=14
如果字符串与正则表达式匹配,您将收到一个数组作为返回值。索引为 0 的元素包含匹配整个模式的字符串,索引 1 之后的元素包含与捕获组所包含的模式匹配的字符串。
这次模式包含三个捕获组,因此捕获的字符串存储在从索引 1 到索引 3 的元素中。
引用匹配字符串的位置
如果执行了 exec 方法并且字符串与正则表达式匹配,则将匹配字符串的第一个字符的索引设置为返回数组的索引属性。可以通过引用 index 属性来查询匹配字符串的位置。目标字符串中的第一个字符的索引为 0,下一个字符的索引为 1,依此类推。
看看下面的示例。
let regexp = /20\d{2}-\d{2}-\d{2}/;
let result = regexp.exec('Today is 2022-09-15');
console.log(result[0]);
>> 2022-09-15
console.log('lastIndex=' + result.index);
>> lastIndex=9
在目标字符串中,我能够引用与正则表达式匹配的字符串的第一个字符的索引。
如果设置了全局标志
可以通过在模式末尾写入 g 来设置全局标志。
/图案/g
如果正则表达式设置了全局标志,那么当执行 exec 方法并且字符串与正则表达式匹配时,正则表达式对象的 lastIndex 属性的值将设置为匹配字符串中下一个字符的索引. (如果未设置全局标志,即使 exec 方法匹配,lastIndex 也将保持为 0)。
let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';
let result = regexp.exec(str);
console.log(result[0]);
>> Sunday
console.log('lastIndex=' + regexp.lastIndex);
>> lastIndex=6
之后,如果将相同的字符串指定为同一个正则表达式的参数并执行exec方法,就会从当前lastIndex所指示的字符串的位置获取与正则表达式匹配的字符串。如果再次匹配,将再次更新 lastIndex 属性的值。
let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';
let result = regexp.exec(str);
console.log(result[0]);
>> Sunday
console.log('lastIndex=' + regexp.lastIndex);
>> lastIndex=6
result = regexp.exec(str);
console.log(result[0]);
>> Monday
console.log('lastIndex=' + regexp.lastIndex);
>> lastIndex=13
如果执行exec方法时正则表达式不匹配,lastIndex会返回0。
let regexp = /[A-Z].+?(day)/g;
let str = 'Sunday Monday Tuesday';
let result = regexp.exec(str);
while (result !== null){
console.log(result[0]);
console.log(result[1]);
console.log('lastIndex=' + regexp.lastIndex);
result = regexp.exec(str);
}
console.log('lastIndex=' + regexp.lastIndex);
>> Sunday
>> day
>> lastIndex=6
>> Monday
>> day
>> lastIndex=13
>> Tuesday
>> day
>> lastIndex=21
>> lastIndex=0
通过像这样设置一个全局标志,就可以检查正则表达式是否多次匹配同一个字符串,如果匹配,就可以得到字符串。
如果目标字符串与正则表达式匹配,则 String 对象的实例方法搜索返回第一个匹配字符串的第一个字符的索引。本节介绍如何使用 String 对象的搜索方法。
search如何使用搜索方法
如果目标字符串与正则表达式匹配,则 String 对象的搜索方法返回第一个匹配字符串的索引。格式如下。
string.search(正则表达式对象)
如果字符串与参数中指定的正则表达式匹配,则返回第一个匹配字符串的第一个字符的索引。如果没有匹配项,则返回 -1。目标字符串中的第一个字符的索引为 0,下一个字符的索引为 1,依此类推。
看看下面的示例。
let regexp = /ball/;
let str1 = 'baseball and football';
let str2 = 'Make a cake tomorrow';
console.log(str1.search(regexp));
>> 4
console.log(str2.search(regexp));
>> -1
第一个字符串匹配正则表达式。目标字符串中有两处匹配正则表达式,但第一个匹配的字符串返回 4,即字符串中第一个字符的索引。返回 -1,因为以下字符串与正则表达式不匹配。
一个类似的方法是 RegExp 对象的测试方法。
如果目标字符串与正则表达式匹配,则 String 对象的实例方法 match 会检索字符串的匹配部分。另外,如果正则表达式模式中包含捕获组,则也获取匹配该捕获组的字符串。如果你设置了一个全局标志,你也可以一次获取所有匹配目标字符串的字符串。这里我们将解释如何使用String对象的match方法。
match如何使用匹配方法
S如果目标字符串与正则表达式匹配,则 String 对象的 match 方法会检索匹配的字符串。格式如下。
string.match(正则表达式对象)
如果字符串与参数中指定的正则表达式匹配,则返回包含匹配字符串的数组。如果没有匹配项,则返回 null。在返回值数组中,索引为 0 的元素包含匹配整个模式的字符串,索引 1 之后的元素包含匹配 set 捕获组所包围的模式的字符串。(如果您没有设置捕获组,则索引 1 之后没有元素)。
数组[0] 匹配整个模式的字符串
数组[1] 匹配捕获组1的字符串
数组[2] 匹配捕获组2的字符串
・・・
数组[n] 匹配捕获组n的字符串
看看下面的示例。对于首先不包含捕获组的模式。
let regexp = /20\d{2}-\d{2}-\d{2}/;
let str1 = 'Today is 2020-08-14';
let str2 = 'Yesterday is 1998-12-07';
let result1 = str1.match(regexp);
console.log(result1[0]);
>> 2020-08-14
let result2 = str2.match(regexp);
console.log(result2[0]);
>> TypeError: Cannot read property '0' of null
如果字符串与正则表达式匹配,您将收到一个数组,其中包含与整个模式匹配的字符串作为索引 0 处元素的值。但是,如果没有匹配项,返回值将为 null,并且尝试获取索引为 0 的元素而不是 null 将引发 TypeError。添加条件分支是否为null或处理异常如下。
let regexp = /20\d{2}-\d{2}-\d{2}/;
let str = 'Yesterday is 1998-12-07';
let result = str.match(regexp);
try{
console.log(result[0]);
} catch(e) {
console.log('Not Match');
}
>> Not Match
如果模式包含捕获组
那么如果模式包含一个捕获组。要创建捕获组,请将模式括在括号 () 中。然后就可以得到与捕获组中设置的模式部分相匹配的字符串。
请看下面的示例。
let regexp = /(20\d{2})-(\d{2})-(\d{2})/;
let str = 'Today is 2020-08-14';
let result = str.match(regexp);
for (let i = 0 ; i < result.length ; i++){
console.log('i=' + i + ', match=' + result[i]);
}
>> i=0, match=2020-08-14
>> i=1, match=2020
>> i=2, match=08
>> i=3, match=14
如果字符串与正则表达式匹配,您将收到一个数组作为返回值。索引为 0 的元素包含匹配整个模式的字符串,索引 1 之后的元素包含与捕获组所包含的模式匹配的字符串。
这次模式包含三个捕获组,因此捕获的字符串存储在从索引 1 到索引 3 的元素中。
如果模式包含命名的捕获组
还可以在 JavaScript 中使用命名捕获组。格式如下。
(?<组名> 模式)
在未命名捕获组的情况下,捕获的字符串可以通过引用作为match方法返回值的数组中索引1之后的元素的值来获取,但是在命名捕获组中捕获的字符串可以按照以下格式引用。
数组.groups.组名
请看下面的示例。
let regexp = /(?<year>20\d{2})-(?<month>\d{2})-(?<day>\d{2})/;
let str = 'Today is 2020-08-14';
let result = str.match(regexp);
let year = result.groups.year;
let month = result.groups.month;
let day = result.groups.day;
console.log(year + '年' + month + '月' + day + '日');
>> 2020年08月14
它在一个命名的捕获组中获取每个捕获,并将它们一起打印在一个字符串中。可以做的事情不管是命名还是未命名都是一样的,但是我觉得指定组名而不是指定捕获组号来获取捕获会让代码更容易理解。
引用匹配字符串的位置
当执行 match 方法并且字符串与正则表达式匹配时,匹配字符串的第一个字符的索引被设置为返回数组的索引属性。可以通过引用 index 属性来查询匹配字符串的位置。目标字符串中的第一个字符的索引为 0,下一个字符的索引为 1,依此类推。
看看下面的示例。
let regexp = /20\d{2}-\d{2}-\d{2}/;
let str = 'Today is 2022-09-15';
let result = str.match(regexp);
console.log(result[0]);
>> 2022-09-15
console.log(result.index);
>> 9
在目标字符串中,我能够引用与正则表达式匹配的字符串的第一个字符的索引。
如果设置了全局标志
您可以通过在模式末尾写入 g 来设置全局标志。
/图案/g
如果为正则表达式设置了全局标志,则执行 match 方法将返回一个数组,其中包含目标字符串中与正则表达式匹配的所有字符串。如果设置了全局标志,即使在模式中设置了捕获组,您也将无法获得捕获。
请看下面的示例。
let regexp = /[A-Z].+?day/g;
let str = 'Sunday Monday Tuesday';
let result = str.match(regexp);
for (let i = 0 ; i < result.length ; i++){
console.log(result[i]);
}
>> Sunday
>> Monday
>> Tuesday
我能够获得与目标字符串中的模式匹配的所有字符串。
String 对象实例方法 split 用指定的分隔符分割字符串并返回包含每个元素的数组作为返回值,但您也可以为分隔符指定正则表达式模式。本文演示了如何将正则表达式模式用作字符串对象的 split 方法的分隔符。
将正则表达式指定为分隔符
String 对象的 split 方法用指定的分隔符分割目标字符串,并返回一个包含每个分割字符串作为元素的数组。格式如下。
string.split([分隔符[, 最大分割数]])
可以指定一个字符串作为参数定界符,但您也可以指定一个正则表达式对象。
文字列.split([正規表現[, 最大分割回数]])
使用与正则表达式匹配的定界符拆分目标字符串。
看看下面的示例。
let msg = `早上好。今天、一大早就是晴天
浑身舒服。是散步的一个好天气`;
let msgAry = msg.split(/[。、\n]/);
console.log(msgAry);
>> ["早上好", "今天", "一大早就是晴天", "浑身舒服", "是散步的一个好天气`", ""]
使用模板文字输入目标字符串,包括换行符。在 split 方法的参数中指定的正则表达式模式中,我指定了一个匹配“.”、“,”或“\n(换行符)”的模式。当执行 split 方法时,目标字符串被正则表达式中指定的三个字符中的任何一个分割。
通过这种方式指定一个正则表达式对象作为分隔符,可以更加灵活地拆分目标字符串。
String对象的实例方法replace将一个字符串中的指定字符串替换为另一个字符串并返回新的字符串。也可以这样做。这时候也可以通过设置一个全局选项一次性全部替换掉。在这里,我将解释如何使用正则表达式模式使用 String 对象的 replace 方法指定要替换的字符串。
使用正则表达式指定替换目标
String 对象的 replace 方法返回一个新字符串,该字符串将目标字符串中的指定字符串替换为另一个字符串。格式如下。
string.replace(要替换的字符串,新字符串)
您可以指定一个固定字符串作为替换参数的字符串,但您也可以指定一个正则表达式对象。
string.replace(正则表达式,新字符串)
用第二个指定字符串替换目标字符串中与第一个指定正则表达式匹配的字符串。不修改目标字符串,返回替换后的新字符串。
如果正则表达式没有设置全局标志,则只会替换目标字符串中第一次出现的正则表达式。如果正则表达式设置了全局标志,则所有匹配的字符串都将被替换。
看看下面的示例。
let str = 'Border Color is Red, Line Color is RED';
let newstr = str.replace(/(Red|RED)/, 'red');
console.log(newstr);
>> Border Color is red, Line Color is RED
如果目标字符串中包含 Red 或 RED,则将其替换为红色。如果没有像本示例中那样在正则表达式对象中设置全局标志,则仅替换第一个匹配的字符串。
这次是设置全局标志时的示例。
let str = 'Border Color is Red, Line Color is RED';
let newstr = str.replace(/(Red|RED)/g, 'red');
console.log(newstr);
>> Border Color is red, Line Color is red
这次设置了全局标志,因此替换了目标字符串中与正则表达式匹配的所有字符串。
引用捕获组匹配的字符串
replace 方法允许您使用美元符号 ($) 编写一个特殊值作为要替换的新字符串。
$& 匹配的子串
$` 匹配部分之前的字符串
$' 匹配部分之后的字符串
$$ $的字符
除了上述之外,如果你指定一个正则表达式作为要替换的字符串,并且捕获组包含在正则表达式中,你可以使用$1, $2, …在捕获组中捕获。你可以参考已创建的字符串。
$1, $2, ... 捕获组捕获的字符串
看看下面的示例。
let str = '生日是 1994-04-21';
let regexp = /(\d{4})-(\d{2})-(\d{2})/;
let newstr = str.replace(regexp, '$1年$2月$3日');
console.log(newstr);
>> 生日是 1994年04月21日
在我们的示例中,正则表达式模式包含三个捕获组。在要替换的新字符串中,我们使用$1 $2 $3 来引用捕获组捕获的字符串并指定要替换的新字符串。
指定一个函数作为要替换的新字符串
replace 方法的第二个参数指定要替换的新字符串,但您也可以指定回调函数而不是字符串。如果指定函数,则当第一个参数中指定的字符串或正则表达式匹配时将调用该函数,并将函数的返回值替换为新值。
string.replace(正则表达式,函数)
该函数在调用时最多接收以下参数。获取所需数量的参数并使用 return 语句返回要在功能块内替换的字符串。
match 匹配模式的字符串
c1,c2,... 当模式包含捕获组时捕获的字符串
offset 匹配字符串中第一个字符的索引
str 目标字符串
看看下面的示例。
let str = 'Border Color is GREEN, Line Color is RED';
let newstr = str.replace(/[A-Z].+?\b/g, function(match){
return match.toLowerCase();
});
console.log(newstr);
>> border color is green, line color is red
在这个例子中,我们指定了一个正则表达式模式来匹配以大写字母开头的单词并执行替换。要替换的新字符串是在回调函数中将所有匹配的字符串转换为小写的return 语句。由于我们设置了全局标志,目标字符串中与正则表达式匹配的所有字符串都将被替换。