🥳常见正则表达式用法汇总表:
| 正则表达式 |
描述 |
[abc] |
匹配 a 或 b 或 c 其中的一个字符 |
[^abc] |
匹配除了 a、b、c 外的任何单个字符 |
[a-zA-Z0-9] |
匹配任何字母或数字 |
. |
匹配除换行符外的任何字符 |
\s |
匹配任何空白字符(空格、制表符、换行符等) |
\S |
匹配非空白字符 |
\d |
匹配任何数字字符(等价于 [0-9]) |
\D |
匹配非数字字符 |
\w |
匹配任何字母、数字或下划线字符(等价于 [a-zA-Z0-9_]) |
\W |
匹配非单词字符(非字母、数字、下划线) |
\b |
匹配单词边界 |
\B |
匹配非单词边界 |
^ |
匹配字符串的开始 |
$ |
匹配字符串的结束 |
a* |
匹配零个或多个 a 字符 |
a? |
匹配零个或一个 a 字符 |
a+ |
匹配一个或多个 a 字符 |
a{3} |
匹配 a 字符恰好重复 3 次 |
a{3,} |
匹配 a 字符重复 3 次或更多次 |
a{3,5} |
匹配 a 字符重复 3 到 5 次 |
? |
非贪婪匹配(最小匹配) |
(abc) |
分组,捕获匹配的内容 |
(?:abc) |
非捕获分组,不捕获匹配的内容 |
a(?=b) |
正向断言,匹配前面是 a 且后面是 b 的位置 |
a(?!b) |
负向断言,匹配前面是 a 且后面不是 b 的位置 |
(?<=b)a |
反向断言,匹配前面是 b 后面是 a 的位置 |
(?<!b)a |
反向负向断言,匹配前面不是 b 后面是 a 的位置 |
(?<name>a) |
命名分组,捕获匹配的内容并命名为 name |
\k<name> |
引用命名分组 name |
\n |
引用第 n 号捕获组 |
\xhh |
匹配十六进制的字符 hh |
\uhhhh |
匹配 Unicode 字符 hhhh(四个十六进制数字) |
\u{hhhh} |
匹配 Unicode 字符 hhhh(四个十六进制数字,u 标志启用) |
\cX |
匹配控制字符 X |
\0 |
匹配空字符 |
\a |
匹配 alert 字符(响铃符号) |
\t |
匹配制表符(Tab) |
\n |
匹配换行符(Line feed) |
\v |
匹配垂直制表符 |
\f |
匹配换页符 |
\r |
匹配回车符 |
\e |
匹配 escape 字符 |
[\b] |
匹配退格符 |
我觉得正则还是挺好学的,稍微花个一下午的时间大概就全弄懂了,正则太强大了,学会对于数据筛查方便不少,hhh👌
部分表达式详细解释
1. 字符集
[abc]
匹配 a、b 或 c 中的任意一个字符。
- 例如,
[abc] 可以匹配:a、b、c。
- 不能匹配:
d 或其他字符。
[^abc]
匹配不是 a、b 或 c 的任意字符。
- 例如,
[^abc] 可以匹配:d、e、1、2 等。
- 不能匹配:
a、b、c。
[a-zA-Z0-9]
匹配任何小写字母、大写字母或数字。这个表达式表示一个字符范围。
- 例如,
[a-zA-Z0-9] 可以匹配:a、A、z、Z、0、9 等。
- 不能匹配:空格、符号等非字母数字字符。
2. 常用元字符
.
匹配任意字符(除换行符 \n 之外)。
- 例如,
a.b 可以匹配:aab、axb、a1b 等。
- 不能匹配:
ab(没有 . 字符)。
\s
匹配空白字符(包括空格、制表符、换行符等)。
- 例如,
\s 可以匹配: (空格)、\t(制表符)、\n(换行符)等。
\S
匹配非空白字符,即除空格、制表符、换行符之外的任何字符。
\d
匹配任何数字字符(0 到 9)。
\D
匹配非数字字符,即除 0 到 9 以外的所有字符。
\w
匹配字母、数字或下划线(即 a-z、A-Z、0-9、_)。
\W
匹配非单词字符,即不是字母、数字或下划线的字符。
3. 边界匹配
\b
匹配单词边界(即单词与非单词字符之间的位置)。
- 例如,
\bword\b 可以匹配:word、word!、word. 等。
\B
匹配非单词边界(即不是单词和非单词字符之间的位置)。
- 例如,
\Bword\B 可以匹配:word1、1word 等。
^
匹配输入字符串的开始位置。
- 例如,
^abc 可以匹配:abc(仅当字符串从 abc 开始时)。
$
匹配输入字符串的结束位置。
- 例如,
abc$ 可以匹配:abc(仅当字符串以 abc 结尾时)。
4. 量词
a\*
匹配零次或多次 a。
- 例如,
a* 可以匹配:空字符串、a、aa、aaa 等。
a?
匹配零次或一次 a。
a+
匹配一次或多次 a。
a{3}
匹配恰好 3 次 a。
- 例如,
a{3} 可以匹配:aaa,不能匹配:aa 或 aaaa。
a{3,}
匹配至少 3 次 a。
- 例如,
a{3,} 可以匹配:aaa、aaaa、aaaaa 等。
a{3,5}
匹配 3 到 5 次 a。
- 例如,
a{3,5} 可以匹配:aaa、aaaa、aaaaa 等,但不能匹配:aa 或 aaaaaa。
?
使量词变成非贪婪匹配(匹配尽可能少的字符)。
- 例如,
<.*?> 会匹配 HTML 标签的最短内容,而不是从 < 到最后一个 > 之间的所有内容。
5. 分组和断言
()
分组,用于组合多个部分。
- 例如,
(abc) 可以将 abc 视为一个单独的单位,可以使用反向引用或应用量词。
(?:a)
非捕获分组,和普通分组相同,但不记录匹配的内容(即不创建捕获组)。
- 例如,
(?:abc) 匹配 abc,但不会创建捕获组。
a(?=b)
正向断言,匹配后面紧跟 b 的 a。
- 例如,
a(?=b) 可以匹配 a,但仅当它后面跟着 b 时。
a(?!b)
正向否定断言,匹配后面不跟 b 的 a。
- 例如,
a(?!b) 可以匹配 a,但仅当它后面不跟着 b 时。
(?<=b)a
反向断言,匹配前面是 b 的 a。
- 例如,
(?<=b)a 可以匹配 a,仅当它前面是 b 时。
(?<!b)a
反向否定断言,匹配前面不是 b 的 a。
- 例如,
(?<!b)a 可以匹配 a,但仅当它前面不是 b 时。
(?<name>a)
命名分组,用于为捕获组指定一个名称。
- 例如,
(?<year>\d{4}) 将匹配 4 位数字,并将该匹配命名为 year。
\k<name>
命名反向引用,引用之前命名分组的内容。
- 例如,
(\d{3})\k<1> 可以匹配一个三位数后跟着相同的三位数。
6. 其他特殊字符
\n
匹配换行符。
\xhh
匹配十六进制值 hh 的字符,例如:\x41 匹配字符 A。
\uhhhh
匹配 Unicode 字符 hhhh,例如:\u0041 匹配字符 A。
\cX
匹配控制字符。例如,\cA 匹配控制字符 ^A。
\0
匹配空字符(null字符)。
\a
匹配警告字符(alert)。
\t
匹配制表符。
\v
匹配垂直制表符。
\f
匹配换页符。
\r
对于分组和断言的使用方式
1. 普通分组(捕获分组)
- 作用:将括号中的内容分组,并为该组分配一个编号,用于后续引用或操作。
- 示例:
(abc) 这个表达式会匹配 abc,并且捕获到第一个分组,你可以通过 \1 来引用它。
- 应用场景:
- 捕获特定部分并进行引用,例如反向引用。
- 对某个部分应用量词,比如
(abc)+ 匹配一个或多个 abc。
2. 非捕获分组
- 作用:与普通分组类似,但不对分组内容进行捕获,也就是说,匹配到的内容不会被记录下来。
- 示例:
(?:abc) 匹配 abc,但是不创建分组(即不会为该部分分配组号)。
- 应用场景:
- 当你需要分组来应用量词,但不希望这个分组参与捕获时,使用非捕获分组。例如,
(?:abc){2} 匹配连续两次 abc,但不捕获分组。
- 避免创建不必要的捕获组,减少内存使用。
3. 正向断言(Lookahead)
- 作用:匹配前面是
a 并且后面紧跟 b 的情况,但不包括 b。即:匹配 a,但仅当它后面是 b 时。
- 示例:
a(?=b) 可以匹配 a,但只有当它后面紧跟着 b 时才会匹配(例如,ab 会匹配 a,但 ac 不会匹配)。
- 应用场景:
- 用来检查后面跟着某些内容,但不包括这些内容本身。例如,在 URL 中匹配
http 后面跟着 s 的情况(如 http:// 和 https://)。
4. 正向否定断言(Negative Lookahead)
- 作用:匹配前面是
a 并且后面不是 b 的情况。即:匹配 a,但仅当它后面不是 b 时。
- 示例:
a(?!b) 可以匹配 a,但是只有当它后面不是 b 时才会匹配(例如,ac 会匹配 a,但 ab 不会匹配)。
- 应用场景:
- 用来排除某些情况,例如,不匹配后面跟着特定字符的部分。
5. 反向断言(Lookbehind)
- 作用:匹配前面是
b 的 a,即:匹配 a,但仅当它前面是 b 时。
- 示例:
(?<=b)a 可以匹配 a,但仅当它前面是 b 时才匹配(例如,ba 会匹配 a,但 ca 不会匹配)。
- 应用场景:
- 用来确保某个部分出现在另一个部分之后,常用于复杂的文本匹配。
6. 反向否定断言(Negative Lookbehind)
- 作用:匹配前面不是
b 的 a,即:匹配 a,但仅当它前面不是 b 时。
- 示例:
(?<!b)a 可以匹配 a,但仅当它前面不是 b 时才匹配(例如,ca 会匹配 a,但 ba 不会匹配)。
- 应用场景:
小结:
- 普通分组(捕获分组):
(abc),用于将内容分组并捕获。它会记录匹配的部分。
- 非捕获分组:
(?:abc),用于分组但不捕获该部分内容。
- 正向断言(Lookahead):
a(?=b),匹配某部分后面跟着某个条件,但不包括该条件。
- 正向否定断言:
a(?!b),匹配某部分后面不跟着某个条件。
- 反向断言(Lookbehind):
(?<=b)a,匹配某部分前面有某个条件。
- 反向否定断言:
(?<!b)a,匹配某部分前面不有某个条件。
相关题目练习
题目1:
匹配一个日期,格式为 YYYY-MM-DD,其中年份可以是四位数,月份是 01 到 12 之间,日期是 01 到 31 之间。请写出正则表达式。
容错性稍微高一点,但是不能识别润平年,简单的判断
1
| ^(\d{4}|\d{2})(\-|\/|\.)\d{1,2}\2\d{1,2}$
|
- **
(\d{4}|\d{2})**:匹配 4 位或 2 位数字,代表年份或日期的部分。(例如:2024 或 24)
- **
(\-|\/\*|\.)**:匹配分隔符 -、/ 或 .。
- **
\d{1,2}**:匹配 1 到 2 位数字,代表月份。
- **
\2**:反向引用,确保分隔符是和前面的 (\-|\/*|\.) 匹配的分隔符相同。
- **
\d{1,2}**:匹配 1 到 2 位数字,代表日期部分。
- **
^ 和 $**:确保整个字符串从头到尾完全匹配。
还一种稍微难一点的,但是我不知道还能不能利用捕获组对年份进行引用将式子缩一下,没尝试过
1 2 3 4
| ^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01])) | (((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30)) | (((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8])) | (((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29))$
|
1. ((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))
- 年份:
(1[6-9]|[2-9]\d)\d{2} 匹配从 1600 年开始的所有年份。
- 月份:
(0?[13578]|1[02]) 匹配 31 天的月份,包括:1、3、5、7、8、10、12 月。
- 日期:
(0?[1-9]|[12]\d|3[01]) 匹配 1 到 31 日(不考虑每个月的实际天数)。
2. (((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))
- 年份:与上面的部分相同。
- 月份:
(0?[13456789]|1[012]) 匹配 30 天的月份,包括:4、6、9、11 月。
- 日期:
(0?[1-9]|[12]\d|30) 匹配 1 到 30 日(不考虑每个月的实际天数)。
3. (((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))
- 年份:与上面的部分相同。
- 月份:
0?2 匹配 2 月(可以有或没有前导零)。
- 日期:
(0?[1-9]|1\d|2[0-8]) 匹配 1 到 28 日(2 月的普通年份日期)。
4. (((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29)
- 年份:
(1[6-9]|[2-9]\d)匹配 1600 年及以后年份。
(0[48]|[2468][048]|[13579][26]) 匹配闰年(能被 4 整除,且不是 100 的倍数,或者能被 400 整除)。
((16|[2468][048]|[3579][26])00) 匹配世纪闰年(如 2000 年、2400 年等)。
- 月份:
0?2 匹配 2 月(可以有或没有前导零)。
- 日期:
29 号,表示 闰年 中的 2 月 29 日。
题目2:
来自HackMyVm上的Challenges 080
(?![a-z])([VHM]{3})(?!\w)(?P[{])R(?![\d])(e)g\3x(_{1})4\4th\3\4(W)in(?P\x7d)$
该正则表达式的含义和匹配模式:
- **
(?![a-z])**:要求在模式前没有小写字母(即这个正则表达式之前的字符不能是小写字母)。
- **
([VHM]{3})**:匹配任意三个字符,这三个字符必须是 ‘V’、’H’ 或 ‘M’ 中的一个。
- **
(?!\w)**:确保在这个三字符后面没有字母、数字或下划线。
- **
(?P<Q>[\{])**:匹配一个左花括号 {,并将其命名为捕获组 Q。
- **
R**:紧接着字符 ‘R’。
- **
(?![\d])**:确保字符 ‘R’ 后面不是数字。
- **
(e)**:紧接着字符 ‘e’。
- **
g**:紧接着字符 ‘g’ 和。
\3:捕获组 3 中的字符(即之前捕获的(e))
x(\_{1}):匹配字符 ‘x’ 后跟一个下划线 _。
- **
4**:匹配数字 ‘4’,然后是捕获组 4(即之前的下划线 _)
\4:然后是捕获组 4(即之前的下划线 _)
th:最后是字符串 ‘th’
- **
\3\4**:匹配之前捕获的组 3 和组 4(即之前的e和下划线)。
- **
(W)**:匹配字符 ‘W’,并将其命名为捕获组 W。
- **
in**:匹配字符串 ‘in’。
- **
(?P<H>\x7d)**:匹配右花括号 十六进制的},并将其命名为捕获组 H。
- **
$**:确保字符串的结束。
所以答案拼凑起来就是HMV{Regex_4_the_Win}