正则表达式学习笔记

Leaining Regexp

Posted by Kenshin on January 5, 2023
本文字符数:英文1270字 | 中文7804字

正则表达式学习笔记

链接

转载自正则表达式 - 菜鸟教程

测试网站

语法

普通字符

普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。

字符 描述
[ABC] 匹配[...]中的所有字符。
[^ABC] 匹配除了[...]中字符的所有字符。
[A-Z] [A-Z]表示一个区间,匹配所有大写字母,[a-z]表示所有小写字母。
. 匹配除换行符(\n\r)之外的任何单个字符,相等于[^\n\r]
[\s\S] 匹配所有。
\d 匹配一个数字字符。等价于[0-9]
\D 匹配一个非数字字符。等价于[^0-9]
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
\S 匹配任何非空白字符。等价于[^ \f\n\r\t\v]
\w 匹配包括下划线的任何单词字符(字母、数字、下划线)。等价于[A-Za-z0-9_]
\W 匹配任何非单词字符。等价于[^A-Za-z0-9_]

非打印字符

字符 描述
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Za-z之一。否则,将c视为一个原义的'c'字符。
\f 匹配一个换页符。等价于\x0c\cL
\n 匹配一个换行符。等价于\x0a\cJ
\r 匹配一个回车符。等价于\x0d\cM
\t 匹配一个制表符。等价于\x09\cI
\v 匹配一个垂直制表符。等价于\x0b\cK
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\n\r\t\v]。注意Unicode正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于[^\f\n\r\t\v]

特殊字符

许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符”转义”,即,将反斜杠字符\放在它们前面。下表列出了正则表达式中的特殊字符:

字符 描述
$ 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配\n\r
() 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。
* 匹配前面的子表达式零次或多次。
+ 匹配前面的子表达式一次或多次。
. 匹配除换行符\n之外的任何单字符。
[ 标记一个中括号表达式的开始。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。
{ 标记限定符表达式的开始。
\| 指明两项之间的一个选择。

限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*+?{n}{n,}{n,m}共6种。

字符 描述
* 匹配前面的子表达式零次或多次。*等价于{0,}
+ 匹配前面的子表达式一次或多次。+等价于{1,}
? 匹配前面的子表达式零次或一次。?等价于{0,1}
{n} n是一个非负整数。匹配确定的n次。
{n,} n是一个非负整数。至少匹配n次。o{1,}等价于o+o{0,}则等价于o*
{n,m} mn均为非负整数,其中n <= m。最少匹配n次且最多匹配m次。o{0,1}等价于o?。请注意在逗号和两个数之间不能有空格。

*+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。

定位符

定位符使您能够将正则表达式固定到行首或行尾。它们还使您能够创建这样的正则表达式,这些正则表达式出现在一个单词内、在一个单词的开头或者一个单词的结尾。

定位符用来描述字符串或单词的边界,^$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。

字符 描述
^ 匹配输入字符串开始的位置。如果设置了RegExp对象的Multiline属性,^还会与\n\r之后的位置匹配。
$ 匹配输入字符串结尾的位置。如果设置了RegExp对象的Multiline属性,$还会与\n\r之前的位置匹配。
\b 匹配一个单词边界,即字与空格间的位置。
\B 非单词边界匹配。

不能将限定符与定位符一起使用。由于在紧靠换行或者单词边界的前面或后面不能有一个以上位置,因此不允许诸如^*之类的表达式。

选择

用圆括号()将所有选择项括起来,相邻的选择项之间用\|分隔。

()表示捕获分组,()会把每个分组里的匹配的值保存起来,多个匹配值可以通过数字n来查看(n是一个数字,表示第n个捕获组的内容)。

但用圆括号会有一个副作用,使相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。

其中?:是非捕获元之一,还有两个非捕获元是?=?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

正则表达式的先行断言(lookahead)和后行断言(lookbehind)

  • exp1(?=exp2):查找exp2前面的exp1
  • (?<=exp2)exp1:查找exp2后面的exp1
  • exp1(?!exp2):查找后面不是exp2exp1
  • (?<!exp2)exp1:查找前面不是exp2exp1

反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从1开始,最多可存储99个捕获的子表达式。每个缓冲区都可以使用\n访问,其中n为一个标识特定缓冲区的一位或两位十进制数。

可以使用非捕获元字符?:?=?!来重写捕获,忽略对相关匹配的保存。

正则表达式后面的全局标记g指定将该表达式应用到输入字符串中能够查找到的尽可能多的匹配。

表达式的结尾处的不区分大小写i标记指定不区分大小写。

多行标记m指定换行符的两边可能出现潜在的匹配。

/\b[\w.%+-]+@[\w.-]+.[a-zA-Z]{2,6}\b/g //匹配邮箱

/\b([a-z]+) \1\b/igm //查找相邻重复单词

/(\w+):\/\/([^/:]+)(:\d)?([^# ])/ //将url拆分协议、域名、端口、页/路径等

修饰符(标记)

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。标记不写在正则表达式里,标记位于表达式之外,格式如:/pattern/flags

字符 描述
i ignore不区分大小写,将匹配设置为不区分大小写。
g global全局匹配,查找所有的匹配项。
m multiline多行匹配,使边界字符^$匹配每一行的开头和结尾,而不是整个字符串的开头和结尾。
s 特殊字符圆点.中包含换行符\n,默认情况下的圆点.是匹配除换行符\n之外的任何字符,加上s修饰符之后,.中包含换行符\n

元字符

字符 描述
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。
^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配\n\r之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配\n\r之前的位置。
* 匹配前面的子表达式零次或多次。*等价于{0,}
+ 匹配前面的子表达式一次或多次。+等价于{1,}
? 匹配前面的子表达式零次或一次。?等价于{0,1}
{n} n是一个非负整数。匹配确定的n次。
{n,} n是一个非负整数。至少匹配n次。o{1,}等价于o+o{0,}则等价于o*
{n,m} mn均为非负整数,其中n <= m。最少匹配n次且最多匹配m次。o{0,1}等价于o?。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符*, +, ?, {n}, {n,}, {n,m}后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
. 匹配除换行符\n\r之外的任何单个字符。要匹配包括\n在内的任何字符,使用像(.\|\n)的模式。
(pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。
(?:pattern) 匹配pattern但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 “或” 字符(\|)来组合一个模式的各个部分是很有用。
(?=pattern) 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?<=pattern) 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。
(?<!pattern) 反向否定预查,与正向否定预查类似,只是方向相反。
x\|y 匹配xy
[xyz] 字符集合。匹配所包含的任意一个字符。
[^xyz] 负值字符集合。匹配未包含的任意字符。
[a-z] 字符范围。匹配指定范围内的任意字符。
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。
\b 匹配一个单词边界,也就是指单词和空格间的位置。
\B 匹配非单词边界。
\cx 匹配由x指明的控制字符。
\d 匹配一个数字字符。等价于[0-9]
\D 匹配一个非数字字符。等价于[^0-9]
\f 匹配一个换页符。等价于\x0c\cL
\n 匹配一个换行符。等价于\x0a\cJ
\r 匹配一个回车符。等价于\x0d\cM
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
\S 匹配任何非空白字符。等价于[^ \f\n\r\t\v]
\t 匹配一个制表符。等价于\x09\cI
\v 匹配一个垂直制表符。等价于\x0b\cK
\w 匹配字母、数字、下划线。等价于[A-Za-z0-9_]
\W 匹配非字母、数字、下划线。等价于[^A-Za-z0-9_]
\xn 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,\x41匹配A\x041则等价于\x04 & 1。正则表达式中可以使用ASCII编码。
\num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,(.)\1匹配两个连续的相同字符。
\n 标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm 标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若nm均为八进制数字(0-7),则\nm将匹配八进制转义值nm
\nml 如果n为八进制数字(0-3),且ml均为八进制数字(0-7),则匹配八进制转义值nml
\un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(C)。

运算符优先级

字符 描述
\ 转义符
(), (?:), (?=), [] 圆括号和方括号
*, +, ?, {n}, {n,}, {n,m} 限定符
^, $, \任何元字符、任何字符 定位点和序列(即:位置和顺序)
\| 替换,”或”操作,字符具有高于替换运算符的优先级。

匹配规则

[AaEeIiOoUu] // 匹配所有的元音字符

[a-z] // 小写字母

[A-Z] // 匹配所有的大写字母

[a-zA-Z] // 匹配所有的字母

[0-9] // 匹配所有的数字

[0-9\.\-] // 匹配所有的数字,句号和减号

[ \f\r\t\n] // 匹配所有的白字符

以上都是单字符

/<iframe(([\s\S])*?)<\/iframe>/ //匹配 iframe 标签

/\b([a-z]+) \1\b/gi 一个单词连续出现的位置。

/(\w+):\/\/([^/:]+)(:\d)?([^# ])/ 匹配一个 URL 解析为协议、域、端口及相对路径。

/^(?:Chapter|Section) [1-9][0-9]{0,1}$/ 定位章节的位置。

/[-a-z]/ a 至 z 共 26个 字母再加一个 - 号。

/ter\b/ 可匹配 chapter,而不能匹配 terminal。

/\Bapt/ 可匹配 chapter,而不能匹配 aptitude。

/Windows(?=95 |98 |NT )/ 可匹配 Windows95 或 Windows98 或 WindowsNT,当找到一个匹配后,从 Windows 后面开始进行下一次的检索匹配。

/^\s*$/ 匹配空行。

/\d{2}-\d{5}/ 验证由两位数字、一个连字符再加 5 位数字组成的 ID 号。

<[a-zA-Z]+.*?>([\s\S]*?)</[a-zA-Z]*?> 匹配 HTML 标记。