📝正则表达式个人备忘
城南花已开 Lv5

🥳常见正则表达式用法汇总表:

正则表达式 描述
[abc] 匹配 abc 其中的一个字符
[^abc] 匹配除了 abc 外的任何单个字符
[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]
    匹配 abc 中的任意一个字符。
    • 例如,[abc] 可以匹配:abc
    • 不能匹配:d 或其他字符。
  • [^abc]
    匹配不是 abc 的任意字符。
    • 例如,[^abc] 可以匹配:de12 等。
    • 不能匹配:abc
  • [a-zA-Z0-9]
    匹配任何小写字母、大写字母或数字。这个表达式表示一个字符范围。
    • 例如,[a-zA-Z0-9] 可以匹配:aAzZ09 等。
    • 不能匹配:空格、符号等非字母数字字符。

2. 常用元字符

  • .
    匹配任意字符(除换行符 \n 之外)。
    • 例如,a.b 可以匹配:aabaxba1b 等。
    • 不能匹配:ab(没有 . 字符)。
  • \s
    匹配空白字符(包括空格、制表符、换行符等)。
    • 例如,\s 可以匹配: (空格)、\t(制表符)、\n(换行符)等。
  • \S
    匹配非空白字符,即除空格、制表符、换行符之外的任何字符。
    • 例如,\S 可以匹配:a1! 等。
  • \d
    匹配任何数字字符(0 到 9)。
    • 例如,\d 可以匹配:123 等。
  • \D
    匹配非数字字符,即除 09 以外的所有字符。
    • 例如,\D 可以匹配:a@! 等。
  • \w
    匹配字母、数字或下划线(即 a-zA-Z0-9_)。
    • 例如,\w 可以匹配:aB1_ 等。
  • \W
    匹配非单词字符,即不是字母、数字或下划线的字符。
    • 例如,\W 可以匹配:!@ (空格)等。

3. 边界匹配

  • \b
    匹配单词边界(即单词与非单词字符之间的位置)。
    • 例如,\bword\b 可以匹配:wordword!word. 等。
  • \B
    匹配非单词边界(即不是单词和非单词字符之间的位置)。
    • 例如,\Bword\B 可以匹配:word11word 等。
  • ^
    匹配输入字符串的开始位置。
    • 例如,^abc 可以匹配:abc(仅当字符串从 abc 开始时)。
  • $
    匹配输入字符串的结束位置。
    • 例如,abc$ 可以匹配:abc(仅当字符串以 abc 结尾时)。

4. 量词

  • a\*
    匹配零次或多次 a
    • 例如,a* 可以匹配:空字符串、aaaaaa 等。
  • a?
    匹配零次或一次 a
    • 例如,a? 可以匹配:空字符串、a
  • a+
    匹配一次或多次 a
    • 例如,a+ 可以匹配:aaaaaa 等。
  • a{3}
    匹配恰好 3 次 a
    • 例如,a{3} 可以匹配:aaa,不能匹配:aaaaaa
  • a{3,}
    匹配至少 3 次 a
    • 例如,a{3,} 可以匹配:aaaaaaaaaaaa 等。
  • a{3,5}
    匹配 3 到 5 次 a
    • 例如,a{3,5} 可以匹配:aaaaaaaaaaaa 等,但不能匹配:aaaaaaaa
  • ?
    使量词变成非贪婪匹配(匹配尽可能少的字符)。
    • 例如,<.*?> 会匹配 HTML 标签的最短内容,而不是从 < 到最后一个 > 之间的所有内容。

5. 分组和断言

  • ()
    分组,用于组合多个部分。
    • 例如,(abc) 可以将 abc 视为一个单独的单位,可以使用反向引用或应用量词。
  • (?:a)
    非捕获分组,和普通分组相同,但不记录匹配的内容(即不创建捕获组)。
    • 例如,(?:abc) 匹配 abc,但不会创建捕获组。
  • a(?=b)
    正向断言,匹配后面紧跟 ba
    • 例如,a(?=b) 可以匹配 a,但仅当它后面跟着 b 时。
  • a(?!b)
    正向否定断言,匹配后面不跟 ba
    • 例如,a(?!b) 可以匹配 a,但仅当它后面不跟着 b 时。
  • (?<=b)a
    反向断言,匹配前面是 ba
    • 例如,(?<=b)a 可以匹配 a,仅当它前面是 b 时。
  • (?<!b)a
    反向否定断言,匹配前面不是 ba
    • 例如,(?<!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. 普通分组(捕获分组)

1
(a)
  • 作用:将括号中的内容分组,并为该组分配一个编号,用于后续引用或操作。
  • 示例(abc) 这个表达式会匹配 abc,并且捕获到第一个分组,你可以通过 \1 来引用它。
  • 应用场景:
    • 捕获特定部分并进行引用,例如反向引用。
    • 对某个部分应用量词,比如 (abc)+ 匹配一个或多个 abc

2. 非捕获分组

1
(?:a)
  • 作用:与普通分组类似,但不对分组内容进行捕获,也就是说,匹配到的内容不会被记录下来。
  • 示例(?:abc) 匹配 abc,但是不创建分组(即不会为该部分分配组号)。
  • 应用场景:
    • 当你需要分组来应用量词,但不希望这个分组参与捕获时,使用非捕获分组。例如,(?:abc){2} 匹配连续两次 abc,但不捕获分组。
    • 避免创建不必要的捕获组,减少内存使用。

3. 正向断言(Lookahead)

1
a(?=b)
  • 作用:匹配前面是 a 并且后面紧跟 b 的情况,但不包括 b。即:匹配 a,但仅当它后面是 b
  • 示例a(?=b) 可以匹配 a,但只有当它后面紧跟着 b 时才会匹配(例如,ab 会匹配 a,但 ac 不会匹配)。
  • 应用场景:
    • 用来检查后面跟着某些内容,但不包括这些内容本身。例如,在 URL 中匹配 http 后面跟着 s 的情况(如 http://https://)。

4. 正向否定断言(Negative Lookahead)

1
a(?!b)
  • 作用:匹配前面是 a 并且后面b 的情况。即:匹配 a,但仅当它后面不是 b
  • 示例a(?!b) 可以匹配 a,但是只有当它后面不是 b 时才会匹配(例如,ac 会匹配 a,但 ab 不会匹配)。
  • 应用场景:
    • 用来排除某些情况,例如,不匹配后面跟着特定字符的部分。

5. 反向断言(Lookbehind)

1
(?<=b)a
  • 作用:匹配前面是 ba,即:匹配 a,但仅当它前面是 b
  • 示例(?<=b)a 可以匹配 a,但仅当它前面是 b 时才匹配(例如,ba 会匹配 a,但 ca 不会匹配)。
  • 应用场景:
    • 用来确保某个部分出现在另一个部分之后,常用于复杂的文本匹配。

6. 反向否定断言(Negative Lookbehind)

1
(?<!b)a
  • 作用:匹配前面不是 ba,即:匹配 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)$

该正则表达式的含义和匹配模式:

  1. **(?![a-z])**:要求在模式前没有小写字母(即这个正则表达式之前的字符不能是小写字母)。
  2. **([VHM]{3})**:匹配任意三个字符,这三个字符必须是 ‘V’、’H’ 或 ‘M’ 中的一个。
  3. **(?!\w)**:确保在这个三字符后面没有字母、数字或下划线。
  4. **(?P<Q>[\{])**:匹配一个左花括号 {,并将其命名为捕获组 Q
  5. **R**:紧接着字符 ‘R’。
  6. **(?![\d])**:确保字符 ‘R’ 后面不是数字。
  7. **(e)**:紧接着字符 ‘e’。
  8. **g**:紧接着字符 ‘g’ 和。
  9. \3:捕获组 3 中的字符(即之前捕获的(e))
  10. x(\_{1}):匹配字符 ‘x’ 后跟一个下划线 _
  11. **4**:匹配数字 ‘4’,然后是捕获组 4(即之前的下划线 _
  12. \4:然后是捕获组 4(即之前的下划线 _
  13. th:最后是字符串 ‘th’
  14. **\3\4**:匹配之前捕获的组 3 和组 4(即之前的e和下划线)。
  15. **(W)**:匹配字符 ‘W’,并将其命名为捕获组 W
  16. **in**:匹配字符串 ‘in’。
  17. **(?P<H>\x7d)**:匹配右花括号 十六进制的},并将其命名为捕获组 H
  18. **$**:确保字符串的结束。

所以答案拼凑起来就是HMV{Regex_4_the_Win}

由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 258.9k