正则表达式基础语法
由于我经常忘记正则表达式的用法,所有本博客主要是以备忘录的形式记录正则表达式的基础语法。需要注意正则表达式的语法其实并不统一。
目的
正则表达式是操作字符的一种语法,最常用于匹配字符串中的某部分。正则表达式的英文是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*,可以匹配do和dogggg |
+ |
匹配前面字符1次或多次,比如dog+,可以匹配dog和dogggg |
? |
匹配前面字符0次或1次。比如dog?,可以匹配do和dog |
? |
表示非贪婪匹配,比如<div> hello world </div>,如果是<.*>,会返回<div> hello world </div>;如果是<.*?>,则只会返回<div>和</div>。所以前面讲的都是贪婪匹配,即只要满足条件就尽可能多的匹配;?相当于是对前面的贪婪匹配进行限制,把前面讲的语法限制为非贪婪匹配,即只匹配满足条件的最小单位(?这个特殊字符用法比较多,需要额外注意) |
{n} |
匹配前面的字符n次 |
{n,} |
匹配前面的字符至少n次 |
{n,m} |
匹配前面的字符n-m次,至少n次,最多m次 |
到这里可以看看这个例子了。

^表示匹配字符串的开头。[a-zA-Z0-9_-]表示字符集,包含小写字母、大写字母、数字、下划线和连接字符 -。{3,15}表示前面的字符集最少出现 3 次,最多出现 15 次,从而限制了用户名的长度在 3 到 15 个字符之间。$表示匹配字符串的结尾。
分组
类比编程的语法来讲,可以看作是一个临时变量,之后可以通过捕获,获取到匹配到的值。也可以看作是一个整体的表达式,里面可以是(cat|dog)
| 语法 | 含义 |
|---|---|
(...) |
捕获组 |
(?:...) |
非捕获组,也是一个整个的表达式,只是不作为临时变量 |
例如,匹配hahahaha,应该是(ha)+
零宽断言
之前的语法中,正则引擎都是每个位置都去试试看是否满足条件。而零宽断言就是从当前位置判断,成功就成功,失败就失败,不会再看之后的其他位置。
| 语法 | 含义 |
|---|---|
(?=...) |
正向前瞻:后面必须是 |
(?!...) |
反向前瞻:后面不能是 |
(?<=...) |
正向后顾:前面必须是 |
(?<!...) |
反向后顾:前面不能是 |
零宽断言:
- 零宽:对匹配的宽度是0,满足就满足,不满足就失败,不去尝试其他位置
- 断言:只是检查条件是否合法,不会真把字符匹配进去。类似于
if判断
相关概念理解:
- 正向:表示肯定,后面只能匹配
xxx - 反向:表示否定,后面不能匹配
xxx - 前瞻:前面满足条件后再向右看,检查后面的内容
- 后顾:后面满足条件后再向左看,检查前面的内容
前瞻后顾如果理解困难,可以直接理解为要把判断条件放在字符的前面还是后面。如果是前瞻,那么放后面;如果是后顾,那么放前面。
举例:
a(?=b):正向前瞻,匹配到a后,后面必须是b。匹配到ab,但是最终返回只会返回a,因为零宽断言只是判断a(?!b):反向前瞻,匹配到a后,后面不能是b。匹配到ac,但是最后返回的还是只有a(?<=\$)\d+:正向后顾,匹配到数字100后,看前面是不是$,如果是就匹配到$100,但是最终返回的还是100(?<!\$)\d+:反向后顾,匹配到数字100后,看前面是不是$,如果不是就匹配到$100,但是最终返回的还是100
实际情景:现在有很多行字符串,选择其中不包含免费的字符串
- 不包含:反向
- 整个字符串里都不包含:前瞻。这里可能有点难理解,也就是直接从字符串开头开始匹配,看后面是否有免费字符。
答案:^(?!.*免费),表示从字符串开头开始匹配判断后面是否存在免费字符。但是这不能返回结果,因为零宽断言只是判断。完整的是^(?!.*免费).*$,需要分成两部分看,前面半部分是^(?!.*免费),后面半部分是.*$。前面相当于一个判断,筛选出来了不包含免费字符的字符串,后面才真正返回字符,而且是一直匹配直到字符串结束$。虽然不加$,也能有类似的效果,但是加上后能确保匹配到字符串结束,语义上更完整。

浙公网安备 33010602011771号