正则表达式是模式,提供了一种强大的方法来搜索和替换文本。
在 JavaScript 中,它们可以通过 RegExp 对象使用,并且集成在字符串的方法中。
正则表达式
正则表达式(也称为“regexp”或“reg”)由一个模式和可选的标志组成。
有两种语法可以用来创建正则表达式对象。
“长”语法
regexp = new RegExp("pattern", "flags");
还有“短”语法,使用斜杠 "/"
regexp = /pattern/; // no flags
regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)
斜杠 /.../
告诉 JavaScript 我们正在创建一个正则表达式。它们在正则表达式中的作用类似于字符串中的引号。
在这两种情况下,regexp
都成为内置 RegExp
类的实例。
这两种语法之间的主要区别在于,使用斜杠 /.../
的模式不允许插入表达式(例如,使用 ${...}
的字符串模板字面量)。它们是完全静态的。
当我们在代码编写时就知道正则表达式时,使用斜杠。这是最常见的情况。而 new RegExp
更常用于需要从动态生成的字符串“动态”创建正则表达式时。例如
let tag = prompt("What tag do you want to find?", "h2");
let regexp = new RegExp(`<${tag}>`); // same as /<h2>/ if answered "h2" in the prompt above
标志
正则表达式可能具有影响搜索的标志。
在 JavaScript 中只有 6 个标志
i
- 使用此标志,搜索将不区分大小写:
A
和a
之间没有区别(参见下面的示例)。 g
- 使用此标志,搜索将查找所有匹配项,不使用此标志,将只返回第一个匹配项。
m
- 多行模式(在章节 多行模式的锚点 ^ $,标志 "m" 中介绍)。
s
- 启用“dotall”模式,允许点
.
匹配换行符\n
(在章节 字符类 中介绍)。 u
- 启用完全 Unicode 支持。此标志启用对代理对的正确处理。有关更多信息,请参见章节 Unicode:标志 "u" 和类 \p{...}。
y
- “粘性”模式:在文本中的确切位置进行搜索(在章节 粘性标志 "y",在位置进行搜索 中介绍)
从这里开始,颜色方案是
- regexp –
红色
- 字符串(我们搜索的地方) –
蓝色
- 结果 –
绿色
搜索:str.match
如前所述,正则表达式与字符串方法集成在一起。
方法 str.match(regexp)
在字符串 str
中查找 regexp
的所有匹配项。
它有 3 种工作模式
-
如果正则表达式带有
g
标志,它将返回所有匹配项的数组。let str = "We will, we will rock you"; alert( str.match(/we/gi) ); // We,we (an array of 2 substrings that match)
请注意,
We
和we
都被找到了,因为i
标志使正则表达式不区分大小写。 -
如果没有这样的标志,它只返回第一个匹配项,以数组的形式,其中完整匹配项位于索引
0
处,其他一些详细信息位于属性中。let str = "We will, we will rock you"; let result = str.match(/we/i); // without flag g alert( result[0] ); // We (1st match) alert( result.length ); // 1 // Details: alert( result.index ); // 0 (position of the match) alert( result.input ); // We will, we will rock you (source string)
如果正则表达式的一部分用括号括起来,则该数组除了
0
之外可能还有其他索引。我们将在 捕获组 一章中介绍这一点。 -
最后,如果没有匹配项,则返回
null
(无论是否有g
标志)。这是一个非常重要的细微差别。如果没有匹配项,我们不会收到一个空数组,而是收到
null
。忘记这一点可能会导致错误,例如:let matches = "JavaScript".match(/HTML/); // = null if (!matches.length) { // Error: Cannot read property 'length' of null alert("Error in the line above"); }
如果我们希望结果始终是一个数组,我们可以这样写:
let matches = "JavaScript".match(/HTML/) || []; if (!matches.length) { alert("No matches"); // now it works }
替换:str.replace
str.replace(regexp, replacement)
方法使用 regexp
在字符串 str
中查找匹配项,并将其替换为 replacement
(如果有 g
标志,则替换所有匹配项,否则只替换第一个匹配项)。
例如:
// no flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
// with flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
第二个参数是 replacement
字符串。我们可以在其中使用特殊字符组合来插入匹配项的片段。
符号 | 替换字符串中的操作 |
---|---|
$& |
插入整个匹配项 |
$` |
插入匹配项之前的字符串的一部分 |
$' |
插入匹配项之后的字符串的一部分 |
$n |
如果 n 是一个 1-2 位数字,则它插入第 n 个括号的内容,更多信息请参见 捕获组 一章。 |
$<name> |
插入具有给定 name 的括号的内容,更多信息请参见 捕获组 一章。 |
$$ |
插入字符 $ |
一个使用 $&
的示例
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
测试:regexp.test
regexp.test(str)
方法查找至少一个匹配项,如果找到,则返回 true
,否则返回 false
。
let str = "I love JavaScript";
let regexp = /LOVE/i;
alert( regexp.test(str) ); // true
在本章的后面,我们将学习更多正则表达式,并通过更多示例,以及其他方法。
有关这些方法的完整信息,请参见 RegExp 和 String 的方法 文章。
摘要
- 正则表达式由一个模式和可选的标志组成:
g
、i
、m
、u
、s
、y
。 - 如果没有标志和特殊符号(我们将在后面学习),正则表达式的搜索与子字符串搜索相同。
- 方法
str.match(regexp)
用于查找匹配项:如果存在g
标志,则查找所有匹配项,否则只查找第一个匹配项。 - 方法
str.replace(regexp, replacement)
使用regexp
查找匹配项,并用replacement
替换它们:如果存在g
标志,则替换所有匹配项,否则只替换第一个匹配项。 - 方法
regexp.test(str)
如果存在至少一个匹配项,则返回true
,否则返回false
。
评论
<code>
标签,对于多行代码,请将它们用<pre>
标签包裹,对于超过 10 行的代码,请使用沙箱(plnkr、jsbin、codepen…)。