正则表达式
第1章 概念
1.1 什么是正则表达式?
正则表达式是构成搜索模式(search pattern)的字符序列。当您搜索文本中的数据时,您可使用搜索模式来描述您搜索的内容。正则表达式可以是单字符,或者更复杂的模式。
1.2 正则表达式的用途
正则表达式可用于执行所有类型的文本搜索和文本替换操作。
第2章 基本语法
2.1 正则表达式之字符匹配攻略
2.1.1 修饰符
修饰符可用于大小写不敏感的更全局的搜素:
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) |
m | 执行多行匹配 |
2.1.2 方括号
方括号用于匹配某个范围内的字符:
表达式 | 描述 |
---|---|
[abc] | 匹配方括号之间的任何字符。 |
[^abc] | 匹配任何不在方括号之间的字符。 |
[0-9] | 匹配任何从 0 至 9 的数字。 |
[a-z] | 匹配任何从小写 a 到小写 z 的字符。 |
[A-Z] | 匹配任何从大写 A 到大写 Z 的字符。 |
[A-z] | 匹配任何从大写 A 到小写 z 的字符。 |
[adgk] | 匹配给定集合内的任何字符。 |
[^adgk] | 匹配给定集合外的任何字符。 |
(red|blue|green) | 匹配任何指定的选项。 |
2.1.3 元字符
元字符(Metacharacter)是拥有特殊含义的字符:
元字符 | 描述 |
---|---|
. | 匹配单个字符,除了换行和行结束符。 |
\w | 匹配单词字符。 |
\W | 匹配非单词字符。 |
\d | 匹配数字。 |
\D | 匹配非数字字符。 |
\s | 匹配空白字符。 |
\S | 匹配非空白字符。 |
\b | 匹配单词边界。 |
\B | 匹配非单词边界。 |
\0 | 匹配 NUL 字符。 |
\n | 匹配换行符。 |
\f | 匹配换页符。 |
\r | 匹配回车符。 |
\t | 匹配制表符。 |
\v | 匹配垂直制表符。 |
\xxx | 匹配以八进制数 xxx 规定的字符。 |
\xdd | 匹配以十六进制数 dd 规定的字符。 |
\uxxxx | 匹配以十六进制数 xxxx 规定的 Unicode 字符。 |
\d就是[0-9]。表示是一位数字。记忆方式:其英文是digit(数字)。
\D就是[^0-9]。表示除数字外的任意字符。
\w就是[0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w是word的简写,也称单词字符。
\W是[^0-9a-zA-Z_]。非单词字符。
\s是[ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符。记忆方式:s是space character的首字母。
\S是[^ \t\v\n\r\f]。 非空白符。
.就是[^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符除外。记忆方式:想想省略号...中的每个点,都可以理解成占位符,表示任何类似的东西。
如果要匹配任意字符怎么办?可以使用[\d\D]、[\w\W]、[\s\S]和[^]中任何的一个。
2.1.4 量词
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。 |
n? | 匹配任何包含零个或一个 n 的字符串。 |
n{X} | 匹配包含 X 个 n 的序列的字符串。 |
n{X,Y} | 匹配包含 X 至 Y 个 n 的序列的字符串。 |
n{X,} | 匹配包含至少 X 个 n 的序列的字符串。 |
n$ | 匹配任何结尾为 n 的字符串。 |
^n | 匹配任何开头为 n 的字符串。 |
?=n | 匹配任何其后紧接指定字符串 n 的字符串。 |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。 |
{m,} 表示至少出现m次。
{m} 等价于{m,m},表示出现m次。
? 等价于{0,1},表示出现或者不出现。记忆方式:问号的意思表示,有吗?
+ 等价于{1,},表示出现至少一次。记忆方式:加号是追加的意思,得先有一个,然后才考虑追加。
* 等价于{0,},表示出现任意次,有可能不出现。记忆方式:看看天上的星星,可能一颗没有,可能零散有几颗,可能数也数不过来。
2.1.5 一些符号在表达式中代表抽象的特殊意义:
表达式 | 作用 |
---|---|
^ | 与字符串开始的地方匹配,不匹配任何字符 |
$ | 与字符串结束的地方匹配,不匹配任何字符 |
/b | 匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符 |
| | 左右两边表达式之间 “或” 关系,匹配左边或者右边 |
( ) | (1)在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰 (2)取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到 |
2.1.6 多选分支
一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一。
具体形式如下:(p1|p2|p3),其中p1、p2和p3是子模式,用 |(管道符)分隔,表示其中任何之一。
例如要匹配"good"和"nice"可以使用/good|nice/。测试如下:
var regex = /good|nice/g;
var string = "good idea, nice try.";
console.log( string.match(regex) );
// => ["good", "nice"]
但有个事实我们应该注意,比如我用/good|goodbye/,去匹配"goodbye"字符串时,结果是"good":
var regex = /good|goodbye/g;
var string = "goodbye";
console.log( string.match(regex) );
// => ["good"]
而把正则改成/goodbye|good/,结果是:
var regex = /goodbye|good/g;
var string = "goodbye";
console.log( string.match(regex) );
// => ["goodbye"]
因此,分支结构是惰性的,即当前面的匹配上了,后面的就不再尝试了。
2.1.6 贪婪匹配和惰性匹配
1、贪婪匹配
贪婪匹配,它会尽可能多的匹配。你能给我6个,我就要5个。你能给我3个,我就要3个。反正只要在能力范围内,越多越好。
let regex = /\d{3,6}/g;
let string = "123 1234 12345 123456";
console.log( string.match(regex) );
// => ["123", "1234", "12345", "12345"]
其中正则/\d{3,6}/,表示数字连续出现3到6次。会匹配3位、4位、5位、6位连续数字。
2、惰性匹配
惰性匹配,就是尽可能少的匹配:
var regex = /\d{2,5}?/g;
var string = "123 1234 12345 123456";
console.log( string.match(regex) );
// => ["12", "12", "34", "12", "34", "12", "34", "56"]
其中/\d{2,5}?/表示,虽然2到5次都行,当2个就够的时候,就不在往下尝试了。
3、总结
通过在量词后面加个问号就能实现惰性匹配,因此所有惰性匹配情形如下:
{m,n}?
{m,}?
??
+?
*?
2.2 正则表达式之位置匹配攻略
2.2.1 什么是位置呢?
位置是相邻字符之间的位置。比如,下图中箭头所指的地方:
2.2.2 如何匹配位置呢?
在ES5中,共有6个锚字符:
^ $ \b \B (?=p) (?!p)
1、^和$
^(脱字符)匹配开头,在多行匹配中匹配行开头。
$(美元符号)匹配结尾,在多行匹配中匹配行结尾。
比如我们把字符串的开头和结尾用"#"替换(位置可以替换成字符的!):
var result = "hello".replace(/^|$/g, '#');
console.log(result);
// => "#hello#"
多行匹配模式时,二者是行的概念,这个需要我们的注意:
var result = "I\nlove\njavascript".replace(/^|$/gm, '#');
console.log(result);
/*
#I#
#love#
#javascript#
*/
2、\b和\B
\b是单词边界,具体就是\w和\W之间的位置,也包括\w和^之间的位置,也包括\w和$之间的位置。
比如一个文件名是"[JS] Lesson_01.mp4"中的\b,如下:
var result = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
console.log(result);
// => "[#JS#] #Lesson_01#.#mp4#"
\B就是\b的反面的意思,非单词边界。例如在字符串中所有位置中,扣掉\b,剩下的都是\B的。
具体说来就是\w与\w、\W与\W、^与\W,\W与$之间的位置。
比如上面的例子,把所有\B替换成"#":
var result = "[JS] Lesson_01.mp4".replace(/\B/g, '#');
console.log(result);
// => "#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4"
3、 (?=p)和(?!p)
(?=p),其中p是一个子模式,即p前面的位置。
比如(?=l),表示’l’字符前面的位置,例如:
var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"
而(?!p)就是(?=p)的反面意思,比如:
var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
// => "#h#ell#o#"
二者的学名分别是positive lookahead和negative lookahead。
中文翻译分别是正向先行断言和负向先行断言。
ES6中,还支持positive lookbehind和negative lookbehind。
比如(?=p),一般都理解成:要求接下来的字符与p匹配,但不能包括p的那些字符
第3章 相关方法
3.1 RegExp 对象方法
方法 | 描述 |
---|---|
compile | 编译正则表达式。 |
exec | 检索字符串中指定的值。返回找到的值,并确定其位置。 |
test | 检索字符串中指定的值。返回 true 或 false。 |
3.2 支持正则表达式的 String 对象的方法
方法 | 描述 |
---|---|
search | 检索与正则表达式相匹配的值。 |
match | 找到一个或多个正则表达式的匹配。 |
replace | 替换与正则表达式匹配的子串。 |
split | 把字符串分割为字符串数组。 |
第4章 常见的正则表达式(收集)
4.1 电话
/^1[3-9]\d{9}$/
4.2 密码
- 必须同时包含字母和数字,且长度在6~20位之间
/^(?=.*[0-9])(?=.*[a-zA-Z])[0-9a-zA-Z]{6,20}$/
- 必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$/
- 必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-10之间
/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$/
4.3 验证码
- 4位的数字验证码
/^\d{4}$/
- 6位数字验证码
/^\d{6}$/
4.4 余额
- 千分位显示
/\B(?=(\d{3})+\b)/g