正则笔记

Linux Shell

Posted by gomyck on July 1, 2024

正则表达式是匹配模式,要么匹配字符,要么匹配位置。请记住这句话。

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" + "" + ""

括号() 的作用:

  1. 分组: /(ab)+/ 与 /ab+/

  2. 分支: /^i love (java script)$/
  3. 提取数据: /(\d{4})-(\d{2})-(\d{2})/ string.match(reg) 会返回数组, 分别是 完整的日期, 年, 月, 日 可以用RegExp.$1-9 来提取数据

  4. 替换:
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是“非确定型有限自动机”的简写。