🥳常见正则表达式用法汇总表:
正则表达式 |
描述 |
[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}