正则表达式 详解
正则表达式
最近在做面试准备的时候,突然发现自己对正则还不够熟悉,特写此文,巩固知识,查漏补缺,也给对这个知识点不够熟悉的朋友简单回顾一下。
什么是正则表达式?
使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。
创建正则表达式
- 使用正则表达式字面量,由包含在斜杠
/
之间的模式组成,如下所示:
/* 使用字面量方法 */
const regex1 = /xy+z/;
const regex2 = /^[a-zA-Z]+[0-9]*\W?_$/gi;
在加载JavaScript引擎之后,正则表达式字面量提供正则表达式的编译。当正则表达式保持不变时,使用此方法可获得更好的性能。
- 调用
RegExp
对象的构造函数,如下所示:
/* 使用构造函数方法 */
let regex1 = new RegExp("xy+z");
let regex2 = new RegExp("^[a-zA-Z]+[0-9]*\\W?_$", "gi");
使用构造函数创造正则对象时,需要常规的字符转义规则(在前面加反斜杠 \
),一般使用在匹配模式未知,需要在运行时使用字符串创建。
正则表达式的模式
一个正则表达式是由简单字符和特殊字符组合而成的,例如/abc/
代表匹配包含有子字符串abc
的字符串,当你需要搜索一个包含更多条件的匹配时,例如搜寻一个或者多个字符,或者搜寻空格,那么这个时候就需要使用特殊字符,例如,模式/ab*c/
代表匹配由一个单独的a
,大于等于0个b
,一个单独的c的字符串组合。在字符串'cbbadfabbbc'
中,这个模式匹配了子字符串'abbbc'
。
正则表达式中使用的特殊字符的完整列表和使用规则详见mdn
字符 | 描述 |
---|---|
\ | 转义字符 |
^ | 起始字符 |
$ | 结束字符 |
* | 匹配前一个字符(表达式)0或多次 |
+ | 匹配前一个字符(表达式)1或多次 |
? | 匹配前一个字符(表达式)0或一次 |
. | 匹配除换行符之外的任何单个字符(表达式) |
(x) | 匹配字符‘x’,并且记住匹配项,括号被称为 捕获括号 |
(?:x) | 匹配‘x’,但是不记住匹配项。这种叫做非捕获括号。 |
x(?=y) | 匹配'x'仅仅当‘x’后面跟着'y',这种叫做正向肯定查找。 |
x(?!y) | 匹配'x'仅仅当‘x’后面不跟着‘y’,这个叫做正向否定查找。 |
x|y | 匹配‘x’或者‘y‘ |
{n} | n是一个正整数,匹配了前面一个字符刚好发生了n次。 |
n和m都是整数,匹配前面的字符至少n次,最多m次。 | |
[xyz] | 一个字符集合。匹配方括号中的任意字符,包括转义序列。 |
[^xyz] | 一个反向字符集。它匹配任何没有在方括号中的字符。 |
[\b] | 匹配一个退格(U+0008)。 |
\b | 匹配一个词的边界。 |
\B | 匹配一个非单词边界。 |
\cX | 当X是处于A到Z之间的字符的时候,匹配字符串的一个控制符。 |
\d | 匹配一个数字。 |
\D | 匹配一个非数字字符。 |
\f | 匹配一个换页符。 |
\n | 匹配一个换行符。 |
\r | 匹配一个回车符。 |
\s | 匹配一个空白字符,包括空格,制表符,换页符,换行符。 |
\S | 匹配一个非空白字符。 |
\t | 匹配一个水平制表符。 |
\v | 匹配一个垂直制表符。 |
\w | 匹配一个单字字符。 |
\W | 匹配一个非单字字符。 |
\1 | 在正则表达式中,它返回最后的第n个字捕获的字符串 |
\0 | 匹配NULL字符,不要在这后面跟其他小数 |
\u | 使用Unicode值hhhh匹配字符(十六进制数字) |
使用正则表达式的方法
-
ReExp对象的
exec
和test
的方法方法 描述 exec
一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回null)。 test
一个在字符串中测试是否匹配的RegExp方法,它返回true或false。 -
String对象的
match
、replace
、search
、和split
方法方法 描述 match
一个在字符串中执行查找匹配的String方法,它返回一个数组或者在未匹配到时返回null。 search
一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 replace
一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 split
一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的String方法 你可以使用test或search方法来验证在一个字符串中的正则匹配是否被找到;或者使用exec或match方法获取返回数组。如果你使用exec或match方法并且匹配成功了,那么这些方法将返回一个数组并且更新相关的正则表达式对象的属性和预定义的正则表达式对象(详见下)。如果匹配失败,那么exec方法返回null(也就是false)。
在接下来的例子中,脚本将使用exec方法在一个字符串中查找一个匹配。
var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
如果你不需要访问正则表达式的属性,这个脚本通过另一个方法来创建myArray:
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
如果你想通过一个字符串构建正则表达式,那么这个脚本还有另一种方法:
var myRe = new RegExp("d(b+)d", "g");
var myArray = myRe.exec("cdbbdbsbzd");
console.log(myArray);
// ["dbbd", "bb", index: 1, input: "cdbbdbsbz", groups: undefined]
通过这些脚本,匹配成功后将返回一个数组并且更新正则表达式的属性,如下表所示。
对象 | 属性或索引 | 描述 | 在例子中对应的值 |
---|---|---|---|
myArray |
匹配到的字符串和所有被记住的子字符串。 | ["dbbd", "bb"] |
|
index |
在输入的字符串中匹配到的以0开始的索引值。 | 1 |
|
input |
初始字符串。 | "cdbbdbsbz" |
|
[0] |
匹配到的所有字符串(并不是匹配后记住的字符串)。注:原文"The last matched characters.",应该是原版错误。匹配到的最终字符。 | "dbbd" |
|
myRe |
lastIndex |
下一个匹配的索引值。 | 5 |
source |
模式文本。在正则表达式创建时更新,不执行。 | "d(b+)d" |
在这个例子中如第二种形式所示,你可以使用一个正则表达式创建一个没
匹配成功之后,正则表达式的返回属性可以进行访问,因此如果你需要访问一个正则表达式的属性,你应该首先把它赋值给一个变量 。
使用带括号的子字符串匹配
在一个正则表达式内使用括号,可以存储括号内的子匹配。回调这些括号里的子匹配可以使用数组元素[index]。
下面的实例使用replace()
方法来转换字符串中的单词,在匹配完成之后的替换环节使用替代的$1
,$2
表示第一个和第二个匹配的子字符串。
var re = /(\w+)\s(\w+)/;
var str = "Mike Json";
var newstr = str.replace(re,"$1,$2");
console.log(newstr);
//输出"Mike,Json";
正则表达式修饰符
修饰符 | 描述 |
---|---|
i | 不区分大小写匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
y | 执行“粘性”搜索,匹配从目标字符串的当前位置开始,可以使用y标志。 |
包含修饰符的正则表达式:
/* flages代表修饰符*/
var regexp = /pattern/flages;
var regexp = new RegExp("pattren","flages");
例如,re = /\w+\s/g
将创建一个查找一个或者多个字符后带有空格的正则表达式
var re = /\w+\s/g;
var str = "fee fi fo fum";
var myArray = str.match(re);
console.log(myArray);
这段代码将输出["fee","fi","foo"]。
实例
用字符串字符验证输入
在下面这个例子中,我们期望用户输入一个电话号码,当用户点击“验证”按钮后,我们的脚本开始检查这些数字是否正确。如果输入正确(匹配正则表达式所固定的字符序列),脚本显示一条感谢用户的信息并确认该数字。如果这串数字不合法,脚本提示用户电话号码不正确。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<script type="text/javascript">
var re = /(?:\d{3}|\(\d{3}\))([-\/\.])*\d{8}/;
function testInfo(phoneInput) {
var OK = re.exec(phoneInput.value);
if (!OK)
window.alert(phoneInput.value + '电话号码格式不正确');
else
window.alert('谢谢,你的电话号码是' + OK[0]);
}
</script>
</head>
<body>
<p>请输入你的电话号码,并点击确认按钮。<br>
电话号码格式例如: ###-########.
</p>
<form action="#">
<input id="phone"></input>
<button onclick="testInfo(document.getElementById('phone'));">
Check
</button>
</form>
</body>
</html>