正则基础
写在前面的:
这篇文章来源于去年九月记录的笔记。
忘记当时看的哪一本正则的书籍了,只记得那本书让人入门很快诶~
但我发现才时隔几个月,我竟然就忘光了之前看的内容,看到正则时,竟然有点恍惚。
本想过,采用拍照贴图的方式来写这篇文章,后来还是放弃,觉得在重新整理一遍,温故知新。
1. 正则的作用:用于搜索和替换
2. 匹配单个字符
e.g. Ben is a boy, and Ben is shy.
-
匹配纯文本
Ben(纯文本的正则)
通常默认匹配第一个,JS 提供g(global)
标识返回所有;
正则区分大小写,则 Ben 与 ben 不同,JS 提供i
标识不区分大小写。 -
匹配任意字符
英文字符 (.) 匹配任何一个单个字符、字母、数字、以及本身。
如果要匹配本身,使用转义字符\
总结
1 纯文本正则
2 英文字符(.)
3 匹配英文字符 (.) 需要使用转义 (\. )
3.匹配一组字符
-
匹配多个字符中的某一个
使用[]
定义字符集合,这两个元字符之内的所有字符为集合组的组成部分。
[ns] -> 匹配 n 或 s
-
利用字符集合区间
使用- (连字符)
,在 [] 为范围,在其余地方只为普通字符串,又与自身匹配。
[A-Z0-9a-z] -> 匹配大小写字母,数字之间的任意一个。
- 取非匹配
使用^ (元字符)
,该效果为字符集合里的所有组成字符进行取饭,而不是说该符号后面紧跟的字符或区间。
总结
1 [] 用来定义集合,匹配其中字符之一;
2 字符集合定义:全部列举/使用连字符-
3 ^ 取反
4.使用元字符
-
对特殊字符进行转义
用法:反斜杠字符 (\) + 元字符 -
匹配空白字符
符号 | 用途 |
---|---|
[\b] | 回退,相当于 Backspace |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 制表符,相当于 Tab |
\v | 垂直制表符 |
- 匹配特定字符
符号 | 用途 | 正则 |
---|---|---|
\d | 任意一个数字 | [0-9] |
\D | 任意一个非数字 | [^0-9] |
\w | 任意一个字母、数字、_ | [A-Za-z0-9_] |
\W | 任意一个非字母、非数字、非_ | [^A-Za-z0-9_] |
\s | 任意一个空白字符 | [\f\n\r\t\v] |
\S | 任意一个非空白字符 | [^\f\n\r\t\v] |
5.重复匹配
-
+ 一个或多个
[0-9]+ 匹配一个或多个连续的数字;
[0-9+] 匹配由 0 到 9 和 + 任意一个; -
* 零个或多个
-
? 零个或一个
-
精确匹配
{6} 重复六次
{6,} 至少六次
{6,7} 至少六次,至多7次 -
贪婪型
e.g. This offer is not available to customers living in <B> AK </B> and <B> HI </B>. ❓❓❓想要获得 包含<B></B> 之内的两组数据;
正则:
/<[Bb]>.*<\/[Bb]>/g
实际匹配:<B> AK </B> and <B> HI </B>
修改正则:
/<[Bb]>.*?<\/[Bb]>/g
最终匹配:<B> AK </B> <B> HI </B>
总结
1 产生原因:*,+,{},都是“贪婪”元字符,匹配模式是多多益善而不是适可而止的。即找到最多的,而不是第一个匹配的。
2 解决方法:在末尾加上?即可。
贪婪模式 | 懒惰模式 |
---|---|
* | *? |
+ | +? |
{n, } | {n, }? |
6.位置匹配
e.g. The cat scattered his food all over the room.
❓❓❓想要获得 cat ;
- 单词边界:限定符\b指定单词边界,\B不匹配单词边界
正则:cat
期望得到:Thecat
scattered his food all over the room.
实际得到:Thecat
scat
tered his food all over the room.
正则 | 效果 |
---|---|
\bcat\b | The cat scattered his food all over the room. |
\Bcat\B | The cat scat tered his food all over the room. |
- 字符串边界
开头^,结尾$
7.使用子表达式
- 子表达式:某些短语由多个单词或者字符组成,其实就是一个整体,必须使用
()
扩起来。
正则 | 效果 |
---|---|
{2, } | ;;;;;;;; |
( ){2, } | |
- 子表达式嵌套
e.g. 匹配IP地址;
正则:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
可能已经发现可以优化了,修改为:(\d{1,3}\.)\d{1,3}
这个正则语法无错,但是可能会匹配到 999.888.777.666 这种数据。 - 来源于我的笔记
8.回溯引用:前后一致匹配
-
经典题目:匹配所有 标题标签(<h1>-<h6>以及其结束标签)
var template = ` <h1>This is H1</h1> divided <h3>Wrong Title</h4> `
正则:
/<[hH][1-6]>.*<\/[hH][1-6]>/g
匹配结果:<h1>This is H1</h1> 和 <h3>Wrong Title</h4>
🤔显然这不是最终想要的结果,这时需要了解
回溯引用匹配
1) 回溯引用只能引用子表达式(即捕获括号 () 括起的正则表达式片段)
2)\
用于标识回溯引用,\1
对应第1个子表达式,\2
对应第2个子表达式,以此类推,\0
对应整个正则表达式。
修改正则:/<[hH]([1-6])>.*<\/[hH]\1>/g
- 来源于我的笔记
9.前后查找
- 前提:
在使用正则表达式时,需要匹配固定内容之间的一些内容,但是又不匹配固定内容。比如,在文本 <h1>this is </h1> 中,想要匹配 h1 之间的文本。这时候,就需要使用零宽断言
。 - 概念:
零宽断言正如它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已。 - 分类:
?= (正向前查找)
?! (负向前查找)
?<= (正向后查找)
?<! (负向后查找) - 经典例子:匹配 p 标签之间文本;
正则:<p>这是一个段落</p>
/(?<=<p>).*(?=<\/p>)/
匹配结果:这是一个段落
- 来源于我的笔记1
- 来源于我的笔记2