正则表达式基础语法

由于我经常忘记正则表达式的用法,所有本博客主要是以备忘录的形式记录正则表达式的基础语法。需要注意正则表达式的语法其实并不统一。

目的

正则表达式是操作字符的一种语法,最常用于匹配字符串中的某部分。正则表达式的英文是Regular Expression,也常简写为regex。如果要检验自己写的正则表达式是否正确,可以使用在线正则表达式测试。通常来说,正则表达式是会返回被匹配的部分,而不是被匹配到的整行字符串。

语法

常见字符

语法 说明
abc 匹配字符abc
[abc] 匹配[]中的字符,可以是其中一个,也可以是多个
[^abc] 匹配[]中以外的字符,不能包含abc
\d(等价于[0-9] 匹配数字
\D 匹配非数字
\s 匹配空白字符
\S 匹配非空白符号
\w(相当于[a-zA-Z0-9_] 匹配字母、数字、下划线
\W 匹配非字母、数字、下划线
\b 匹配单词边界,虽然大部分边界可能都是空格,但是也可能是其他特殊字符。比如要专门匹配一个单词很有用,比如\bcat\b
\B 匹配非单词边界,即就在单词内部去匹配

特殊字符

语法 说明
\ 通常来说是作为转义字符,既匹配字符\n,但是会被误认为是匹配换行,所有需要\\n
^ 表示字符串的开头
$ 表示字符串的结尾
. 匹配除了\n外的任意单个字符
* 匹配前面字符0次或多次,比如dog*,可以匹配dodogggg
+ 匹配前面字符1次或多次,比如dog+,可以匹配dogdogggg
? 匹配前面字符0次或1次。比如dog?,可以匹配dodog
? 表示非贪婪匹配,比如<div> hello world </div>,如果是<.*>,会返回<div> hello world </div>;如果是<.*?>,则只会返回<div></div>。所以前面讲的都是贪婪匹配,即只要满足条件就尽可能多的匹配;?相当于是对前面的贪婪匹配进行限制,把前面讲的语法限制为非贪婪匹配,即只匹配满足条件的最小单位(?这个特殊字符用法比较多,需要额外注意)
{n} 匹配前面的字符n次
{n,} 匹配前面的字符至少n次
{n,m} 匹配前面的字符n-m次,至少n次,最多m次

到这里可以看看这个例子了。

img

  • ^ 表示匹配字符串的开头。
  • [a-zA-Z0-9_-] 表示字符集,包含小写字母、大写字母、数字、下划线和连接字符 -。
  • {3,15} 表示前面的字符集最少出现 3 次,最多出现 15 次,从而限制了用户名的长度在 3 到 15 个字符之间。
  • $ 表示匹配字符串的结尾。

分组

类比编程的语法来讲,可以看作是一个临时变量,之后可以通过捕获,获取到匹配到的值。也可以看作是一个整体的表达式,里面可以是(cat|dog)

语法 含义
(...) 捕获组
(?:...) 非捕获组,也是一个整个的表达式,只是不作为临时变量

例如,匹配hahahaha,应该是(ha)+

零宽断言

之前的语法中,正则引擎都是每个位置都去试试看是否满足条件。而零宽断言就是从当前位置判断,成功就成功,失败就失败,不会再看之后的其他位置。

语法 含义
(?=...) 正向前瞻:后面必须是
(?!...) 反向前瞻:后面不能是
(?<=...) 正向后顾:前面必须是
(?<!...) 反向后顾:前面不能是

零宽断言:

  • 零宽:对匹配的宽度是0,满足就满足,不满足就失败,不去尝试其他位置
  • 断言:只是检查条件是否合法,不会真把字符匹配进去。类似于if判断

相关概念理解:

  • 正向:表示肯定,后面只能匹配xxx
  • 反向:表示否定,后面不能匹配xxx
  • 前瞻:前面满足条件后再向右看,检查后面的内容
  • 后顾:后面满足条件后再向左看,检查前面的内容

前瞻后顾如果理解困难,可以直接理解为要把判断条件放在字符的前面还是后面。如果是前瞻,那么放后面;如果是后顾,那么放前面。

举例:

  1. a(?=b):正向前瞻,匹配到a后,后面必须是b。匹配到ab,但是最终返回只会返回a,因为零宽断言只是判断
  2. a(?!b):反向前瞻,匹配到a后,后面不能是b。匹配到ac,但是最后返回的还是只有a
  3. (?<=\$)\d+:正向后顾,匹配到数字100后,看前面是不是$,如果是就匹配到$100,但是最终返回的还是100
  4. (?<!\$)\d+:反向后顾,匹配到数字100后,看前面是不是$,如果不是就匹配到$100,但是最终返回的还是100

实际情景:现在有很多行字符串,选择其中不包含免费的字符串

  • 不包含:反向
  • 整个字符串里都不包含:前瞻。这里可能有点难理解,也就是直接从字符串开头开始匹配,看后面是否有免费字符。

答案:^(?!.*免费),表示从字符串开头开始匹配判断后面是否存在免费字符。但是这不能返回结果,因为零宽断言只是判断。完整的是^(?!.*免费).*$,需要分成两部分看,前面半部分是^(?!.*免费),后面半部分是.*$。前面相当于一个判断,筛选出来了不包含免费字符的字符串,后面才真正返回字符,而且是一直匹配直到字符串结束$。虽然不加$,也能有类似的效果,但是加上后能确保匹配到字符串结束,语义上更完整。

参考文献

  1. 菜鸟教程 正则表达式 - 语法
  2. 正则表达式手册
  3. 正则表达式-语法大全
posted @ 2026-05-20 15:20  顾子郤  阅读(15)  评论(0)    收藏  举报