最近项目中用到正则表达式,每次用到,就查一下看一下正则表达式30分钟入门教程,不久后又忘记,对一些复杂一点的也不是很理解,导致每次都花费很多时间,就彻底整理一遍,找了《正则表达式必知必会》参考,整理出匹配的表达式和文本范例,下次看也高效一点。
定义:正则表达式就是用于描述这些规则的工具。
用途:
- 查找特定的信息(搜索)
- 查找并编辑特定的信息(替换)
元字符
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或者结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
匹配单个字符
表达式:
my
文本:My name is yuan,her name is li,my brother name is ling.
匹配数字
表达式:
\d
file1.txt
\s
表示任意的空白符,包括\r
空格,\n
换行,\t
Tab键,分别匹配空格,Tab键,换行。表达式:
txt\sf
文本:
file1.txt file2.txt file3.txt
file4.txt
单词边界
边界可以由\b
进行限定,\b
不匹配任何字符,其只匹配一个位置,这个位置位于一个能否用来构成单词的字符(也就是和\w
相匹配的字符)和一个不能用来构成单词的字符(也就是与`\W相匹配的字符)之间。
匹配开头为
n
的单词,需要添加元字符\b
,否则会匹配yuan ling
,表达式:
\bn
文本:My name is yuan,her name is li,my brother name is ling.
匹配
li
而不匹配ling
,\b
匹配了单词的开头和结尾表达式:
li\b
文本:My name is yuan,her name is li,my brother name is ling.
^
也是限制匹配词的开始,不过是针对整个字符串,匹配其中开头的My
,而不是中间的my
,表达式为:^my
,$
则是限制字符串的结束
反义符
代码 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意不是数字的字符 |
\B | 匹配不是单词开头或者结束的位置 |
[^X] | 匹配除了X以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的人任意字符 |
[0-9]
表示匹配0-9的数字,和\d
一样。[a-z]
表示匹配a-z的所有单词,[A-Z]
表示匹配A-Z的所有单词,[a-zA-Z]
则匹配所有大小写单词单词。连字符
-
在字符集[ ]之间才有特殊的意义,在字符集外只是一个普通字符,匹配其本身不需要被转义。
转义符
1 | // 以下字符有特殊意义,匹配该字符需要添加 \ |
- 上面的字符在字符集[ ]中会被解释为普通字符,不需要转义,但为了避免误解,最好进行转义。
限定符
代码 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或者一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
在给一个字符集合加上限定符的时候,必须把限定符放在其外面
- 表达式:
n\d*
文本:n n1 n123 - 表达式:
n\d+
文本:n n1 n123 - 表达式:
n\d?
文本:n n1 n123 - 表达式:
n\d{1}
文本:n n1 n123 - 表达式:
n\d{1,}
文本:n n1 n123 - 表达式:
n\d{1,2}
文本:n n1 n123
贪婪与懒惰
正则匹配默认情况下,是匹配尽可能多的字符,即贪婪匹配。如果需要匹配尽可能少的字符,就需要通过限定符转化为懒惰匹配。
代码 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或者1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
注:由于匹配到的文本想通过高亮显示出现,没办法使用代码块,导致<H1>
会被网页识别为标题,因此,下面通过《
替代<
和》
替换>
,一方面在Markdown中正确显示,又在网页中可以正确显示
匹配《H1》标签之间的内容,默认是贪婪匹配,会匹配尽可能的多。
表达式:
《H1》.*《/H1》
文本:
《H1》Welcome to my Homepage《/H1》Content is divided into two sections.《H1》This is not valid HTML《/H1》过度匹配,需要采用懒惰模式,匹配尽可能的少
表达式:
《H1》.*?《/H1》
文本:
《H1》Welcome to my Homepage《/H1》Content is divided into two sections.《H1》This is not valid HTML《/H1》
子表达式
子表达式通过(和)把一系列元素括起来,把其当成一个独立元素使用。
默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的组号为1,第二个为2,以此类推。第0个匹配可以用来代表整个正则表达式。组号必须添加\
进行转义。
在表达式
((A)(B(C)))
中,存在4个分组1
2
3
4((A)(B(C)))
(A)
(B(C))
(C)
捕获
代码 | 说明 |
---|---|
(exp) | 匹配exp,并捕获文本到自动命名的组里 |
(?\ |
匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp) |
(?:exp) | 匹配exp,不捕获匹配的文本,也不给词分组分配组号 |
匹配年份,如果不使用子表达式,则只会匹配19,因为
|
操作符是吧位于它左边和右边的两个部分都作为一个整体来看待的,就变成匹配19
和20\d{2}
表达式:
(19|20)\d{2}
文本:1999
匹配HTML标题中的内容,会发现,H2 对应的 H3 为错误的,不应该被匹配到
表达式:
《H[1-6]》.*?《/H[1-6]》
文本:
《H1》Welcome to my Homepage《/H1》
Content is divided into two sections.
《H2》This is not valid HTML《/H3》如果不想匹配到错误的内容,只要使用回溯引用,确保标签头和标签尾一致。把
[1-6]
作为一个表达式,在后面使用\1
去匹配。表达式:
《H([1-6])》.*?《/H\1》
文本:
《H1》Welcome to my Homepage《/H1》
Content is divided into two sections.
《H2》This is not valid HTML《/H3》如果使用组号进行匹配,在正则表达式复杂的情况下,如果进行修改,比如在前面添加一个分组,所有的分组编号都要进行修改。因此,使用分组重命名就可以避免。
表达式:
《H(?<number>[1-6])》.*?《/H\number》
文本:
《H1》Welcome to my Homepage《/H1》
Content is divided into two sections.
《H2》This is not valid HTML《/H3》有时候在使用
|
的时候,需要用到()
,但是实际上,不需要进行捕获,在后面也不需要用到此分组,为了提高效率,可以使用(?:exp)
表达式:
(19|20)\d{2}《H([1-6])》.*《H\2》
文本:
1993《H1》head《/H1》如果使用
(?:exp)
,则没有该分组了,\2
也需要换成\1
表达式:
(?:19|20)\d{2}《H([1-6])》.*《/H\1》
文本:
1993《H1》head《/H1》
断言
代码 | 说明 |
---|---|
(?=exp) | 正向前查找 |
(?!exp) | 负向前查找 |
(?<=exp) | 正向后查找 |
(?<!exp) | 负向后查找 |
有些时候,匹配到的内容,不是你真正需要的,如果把它搜索出来,再手动去掉,比较麻烦,那么需要被匹配到的文本不包含在最终返回的匹配结果中,也就是“不消费”。
匹配URL地址,把协议名部分提取出来
表达式:
.+(?=:)
文本:
http://www.baidu.com
https://www.baidu.com提取产品中的价格
表达式:
(?<=\$)[0-9.]+
文本:
apple: \$1
banana: \$2匹配数量不匹配价格
表达式:
\b(?<!\$)\d+\b
文本:I paid $30 for 100 apples;
嵌入条件
正则表达式里的条件用?来定义,只有符合条件才执行后面的匹配。
代码 | 说明 | |
---|---|---|
(?(condition)true) | 存在则执行true | |
(?(condition)true\ | false) | 存在则执行true,错误则执行false |
匹配电话号码,如果存在( 则需要),否则需要 -
表达式:
(\()?\d{3}(?(1)\)|-)\d{3}-\d{4}
文本:
123-456-7890
(123)456-7890
(123-456-7890
(123)-456-7890
参考
- 正则表达式30分钟入门教程
- 站长工具 正则测试
- 《正则表达式必知必会》