正则表达式是匹配模式,要么匹配字符,要么匹配位置。请记住这句话。
1.转义符 \
2.括号和方括号 (…)、(?:…)、(?=…)、(?!…)、[…]
3.量词限定符 {m}、{m,n}、{m,}、?、*、+
4.位置和序列 ^ 、$、 \元字符、 一般字符
5. 管道符(竖杠)|
6: 元字符: ^ $. * +? | \ / ( ) [ ] { } =! : - ,
横向模糊指的是,一个正则可匹配的字符串的⻓度不是固定的,可以是多种情况的。
其实现的方式是使用量词。譬如{m,n},表示连续出现最少m次,最多n次。
比如 /ab{2,5}c/ 表示匹配这样一个字符串:第一个字符是 “a”,接下来是 2 到 5 个字符 “b”,最后是字符 “c”。
纵向模糊指的是,一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。
其实现的方式是使用字符组。譬如[abc],表示该字符是可以字符“a”、“b”、“c”中的任何一个。
比如/a[123]b/可以匹配如下三种字符串:”a 1 b”、”a 2 b”、”a 3 b”。
文字匹配部分:
1. {m, n} 表示: 最少m次最多n次出现 比如: /ab{2, 4}c/g 表示 b出现 2 到 4 次
2. /g表示全局匹配(与不加/g的区别在于是否可以继续向后匹配, 对test, split, search方法无效)
1
2
3
4
5
6
7
8
9
10
11
exp: const reg = /gomyck\d/;
const arg 1 = reg.exec('gomyck123xxxxxxgomyck456ooooo'); // arg 1 = gomyck 1
const arg 2 = reg.exec('gomyck123xxxxxxgomyck456ooooo'); // arg 2 = gomyck 1
const arg 3 = reg.match('gomyck123xxxxxxgomyck456ooooo'); //arg 3 = {'gomyck1'}
const arg 4 = reg.match('gomyck123xxxxxxgomyck456ooooo'); //arg 4 = {'gomyck1'}
-------------------------------------------------------------------------------------
const reg = /gomyck\d/g;
const arg 1 = reg.exec('gomyck123xxxxxxgomyck456ooooo'); // arg 1 = gomyck 1
const arg 2 = reg.exec('gomyck123xxxxxxgomyck456ooooo'); // arg 2 = gomyck 4
const arg 3 = reg.match('gomyck123xxxxxxgomyck456ooooo'); //arg 3 = {'gomyck1', 'gomyck4'}
const arg 4 = reg.match('gomyck123xxxxxxgomyck456ooooo'); //arg 4 = {'gomyck1', 'gomyck4'}
3. [xmn] 表示任意匹配, 比如/a[123]b/ 表示 可以为a1b a2b a3b
1
2
3
1.范围表示: - 比如[1-4a-gG-M]
2.匹配 - 可以使用转译符 \ 比如匹配 [a\-z] || [-az] || [az-]
3.排除字符组 ^ (脱字符) 比如: [^ab] 表示不能是a||b
4. 常⻅的简写: [digit] [word] [space character]
1
2
3
4
5
6
7
\d 是 [0-9]。表示是一位数字。
\D 是 [^0-9]。表示除数字外的任意字符。
\w 是 [0-9a-zA-Z_]。表示数字、大小写字母和下划线。记忆方式:w是word的简写,也称单词字符。
\W 是 [^0-9a-zA-Z_]。非单词字符。
\s 是 [ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回⻋符、换⻚符。
\S 是 [^ \t\v\n\r\f]。 非空白符。
. 是 [^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回⻋符、行分隔符和段分隔符除外。
1
2
3
4
5
{m,} 表示至少出现m次。
{m} 等价于{m,m},表示出现m次。
? 等价于{0,1},表示出现或者不出现。
+ 等价于{1,},表示出现至少一次。
* 等价于{0,},表示出现任意次,有可能不出现
5. ?为惰性匹配 有短路的功能 比如: /\d{1,2/}?/g 121231234 => 1, 1, 1 因为匹配一个已经满足条件了 不会继续匹配了
6. 多选分支: | 管道符 可以拼接多个表达式
1
/(express|express)/ 分支结构本身是短路的(惰性)的
7. () 括号为子表达式, 一个表达式可以包含子表达式 子表达式为顺序匹配, 比如 (express1)(express2)(express3) 为先匹配1, 在从 1 的基础上匹配2, 再从 1 2 的基础上匹配 3
位置匹配部分:
1. ^ 和 $ 分别代表字符串的开头与结束 比如 : /^|$/g 表示 匹配字符串的开头和结尾
2. \b 和 \B (单词的概念: 0-9 a-z A-Z)
1
2
3
4
5
6
7
8
9
10
\b代表非单词到单词之间的位置(单词边界), 比如
var result = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
console.log(result);
// => "[#JS#] #Lesson_01#.#mp4#"
因为[ 到 J 为非单词到单词
J到S位单词, 所以没有返回该位置, S 到 ] 为非单词, 所以会插入# 后面同理
\B代表 ^\b 也就是返回字符串中 不同于\b的位置, 但是并不是 单词到单词之间的位置, 会少一些结果集, 实际返回的也是这样(非单词边界)
3. (?=p)与(?!p)
1
2
3
4
5
6
7
8
9
10
(?=p)意思是 p前面的位置 p为子表达式 (?=x) 表示x字符前面的位置 (正向先行断言)
var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"
(?!p) 为^(?!p) 表示不同于(?=p)的位置(负向先行断言)
var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
// => "#h#ell#o#"
(?=exp)也叫零宽先行断言,它匹配文本中的某些位置,这些位置的后面能匹配给定的后缀exp。比如 \b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分), 在查找 I’m singing while you’re dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽后行断言,它匹配文本中的某些位置,这些位置的前面能给定的前缀匹配exp。 比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分), 例如在查找reading a book 时,它匹配ading。
4. 位置的概念, 因此,把/^hello$/写成/^^hello$$$/,是没有任何问题的
1
"hello" == "" + "" + "h" + "" + "ello" + "" + ""
括号() 的作用:
-
分组: /(ab)+/ 与 /ab+/
-
分支: /^i love (java script)$/ -
提取数据: /(\d{4})-(\d{2})-(\d{2})/ string.match(reg) 会返回数组, 分别是 完整的日期, 年, 月, 日 可以用RegExp.$1-9 来提取数据
- 替换:
1
2
3
4
5
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result);
// => "06/12/2017"
其他知识点:
1.反向引用
1
2
3
4
/\d{4}(-|\/|\.)\d{2}\1\d{2}/;
比如: 2016-01-01 2016/11/11 2016.12.23 都可以匹配, 但是 2014-01.23 匹配不了 \1 为引用第一个子式 \2 为第二个
以此类推 如果不存在, 则匹配转以后的子式索引 比如 \2 不存在, 则匹配 2 的转义字符
2.回溯: 也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进), 再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。 而JS的正则引擎是NFA,NFA是“非确定型有限自动机”的简写。