let str = "More about JavaScript at https://javascript.info";
let regexp = /javascript/i;
console.log(regexp.exec(str));
/* [
0 : "JavaScript"
groups:undefined
index: 11
input :"More about JavaScript at https://javascript.info"
] */
let str = "More about JavaScript at https://javascript.info";
let regexp = /javascript/gi;
let result;
while ((result = regexp.exec(str))) {
console.log(`Found ${result[0]} at position ${result.index}`);
// 在位置 11 找到了 JavaScript,然后
// 在位置 33 找到了 javascript
}
这现在也有效,尽管对于较新的浏览器 str.matchAll 通常更方便。
指定位置搜索
我们可以通过手动设置 lastIndex,用 regexp.exec 从给定位置进行搜索。
例如:
let str = "Hello, world!";
let regexp = /\w+/g; // 没有修饰符 "g",lastIndex 属性会被忽略
regexp.lastIndex = 5; // 从第 5 个位置搜索(从逗号开始)
console.log(regexp.exec(str)); // world
let result = "2022/10/24".replace(
/(\d{4})\/(\d{2})\/(\d{2})/g,
(_, y, m, d) => {
return [m, d, y].join("/");
}
);
console.log(result); // 10/24/2022
如果有许多组,用 rest 参数(…)可以很方便的访问:
let result = "2022/10/24".replace(/(\d{4})\/(\d{2})\/(\d{2})/g, (...match) => {
return `${match[2]}/${match[3]}/${match[1]}`;
});
console.log(result); // 10/24/2022
或者,如果我们使用的是命名组,则带有它们的 groups 对象始终是最后一个对象,所以我们可以像这样获取它:
let result = "2022/10/24".replace(
/(?<year>\d{4})\/(?<month>\d{2})\/(?<day>\d{2})/g,
(...match) => {
let groups = match.pop();
return `${groups.month}/${groups.day}/${groups.year}`;
}
);
console.log(result); // 10/24/2022
方法篇,JavaScript 中都有哪些操作正则的方法。
RegExp 对象方法
regexp.test(str)
方法 regexp.test(str) 查找匹配项,然后返回
true/false
表示是否存在。regexp.exec(str)
regexp.exec(str) 方法返回字符串 str 中的 regexp 匹配项, 可指定从位置进行搜索。
基于否具有修饰符 g 其有两种搜索模式。
(1) 没有修饰符 g,则 regexp.exec(str) 会返回与 第一个匹配项,就像 str.match(regexp) 那样。这种行为并没有带来任何新的东西。
(2) 有修饰符 g,可以基于 regexp.lastIndex 位置循环搜索全部。
详细步骤:
过去,在将 str.matchAll 方法添加到 JavaScript 之前,会在循环中调用 regexp.exec 来获取组的所有匹配项:
这现在也有效,尽管对于较新的浏览器
str.matchAll
通常更方便。指定位置搜索
我们可以通过手动设置 lastIndex,用 regexp.exec 从给定位置进行搜索。
例如:
如果正则表达式带有修饰符 y,则搜索将精确地在 regexp.lastIndex 位置执行,不会再进一步。
让我们将上面示例中的 g 修饰符替换为 y。现在没有找到匹配项,因为在位置 5 处没有单词:
当我们需要通过正则表达式在确切位置而不是其后的某处从字符串中“读取”某些内容时,这很方便。
String 对象的方法
str.match(regexp)
str.match(regexp) 方法在字符串 str 中查找 regexp 的匹配项。搜索成功就返回内容,格式为数组,失败就返回 null。
它有三种模式:
str.matchAll(regexp)
方法 str.matchAll(regexp) 是 str.match 的“更新、改进”的变体。
它主要用来搜索所有组的所有匹配项。
与 match 相比有 3 个区别:
如果我们用 for..of 来遍历 matchAll 的匹配项,那么我们就不需要 Array.from 了。
str.split(regexp|substr, limit)
使用正则表达式(或子字符串)作为分隔符来分割字符串。
我们可以用 split 来分割字符串,像这样:
但同样,我们也可以用正则表达式:
另外,因为 split 方法中的正则是用来匹配分隔符,所以全局匹配没有意义。
str.search(regexp)
方法 str.search(regexp) 返回第一个匹配项的位置索引,如果没找到,则返回 -1:
重要限制:search 仅查找第一个匹配项。
如果我们需要其他匹配项的位置,则应使用其他方法,例如用 str.matchAll(regexp) 查找所有位置。
str.replace(str|regexp, str|func)
这是用于搜索和替换的通用方法,是最有用的方法之一。它是搜索和替换字符串的瑞士军刀。
我们可以在不使用正则表达式的情况下使用它来搜索和替换子字符串。
当 replace 的第一个参数是字符串时,它只替换第一个匹配项。
在下面的示例中看到:只有第一个 "/" 被替换为了 "-"。
如要找到所有的连字符,我们不应该用字符串 "/",而应使用带 g 修饰符的正则表达式
/\//g
:第二个参数是替换字符串。我们可以在其中使用特殊字符, 在实际替换时 replace 内部逻辑会自动解析字符串,提取出变量。
例如:
$&
代表匹配结果。`$``代表匹配结果左边的文本。
$n
代表按序号 n 获取对应捕获组的文本。$<name>
代表按 name 为捕获组命名:对于需要“智能”替换的场景,第二个参数可以是一个函数。
每次匹配都会调用这个函数,并且返回的值将作为替换字符串插入。
该函数
func(match, p1, p2, ..., pn, offset, input, groups)
带参数调用:如果正则表达式中没有括号,则只有 3 个参数:func(str, offset, input)。
如果有许多组,用 rest 参数(…)可以很方便的访问:
或者,如果我们使用的是命名组,则带有它们的 groups 对象始终是最后一个对象,所以我们可以像这样获取它:
str.replaceAll(str|regexp, str|func)
这个方法与 str.replace 本质上是一样的,但有两个主要的区别:
如果第一个参数是一个字符串,它会替换 所有出现的 和第一个参数相同的字符串 , 而 replace 只会替换 第一个。 如果第一个参数是一个没有修饰符 g 的正则表达式,则会报错。带有修饰符 g,它的工作方式与 replace 相同。 replaceAll 的主要用途是替换所有出现的字符串。
像这样:
RegExp.$1-$9
非标准$1, $2, $3, $4, $5, $6, $7, $8, $9 属性是包含括号子串匹配的正则表达式的静态和只读属性。
在脚本中使用如
replace
、test
、match
等方法,如果正则中含有捕获组,访问 RegExp 对象的非标准属性$1
和$2
能提取捕获组里面的内容。参考链接