前言
在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要,正则表达式就是用于描述这些规则的工具,换句话说正则表达式是一种工具,它定义了字符串的匹配模式。今天我们在日常工作中处理的信息基本上都是文本数据,我们希望计算机能够识别和处理符合某些模式的文本,正则表达式就显得非常重要了。
本文为《正则表达式30分钟入门教程》的学习笔记
常用元字符
知识点
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
例子
1 | 匹配区号为3位的电话号码:0\d{2}-\d{8} |
字符转义
适用场景
想要查找一个*.^等有特殊含义的字符时候,我们需要用到转义符号\
例子
1 | 查找*:\* |
重复
知识点
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
例子
1 | 验证是否为wifi密码规定字符大小:[a-z0-9A-Z]{8,} |
字符类
适用场景
想要匹配没有预定义元字符的字符集合
知识点
在方括号中列出他们
例子
1 | 想要匹配格式如(010)88886666或者022-22334455或者02812345678: |
分支条件
知识点
正则表达式中的分支条件指的是有几种规则,如果满足其中规定任意一种规则都应该当成匹配,具体语法是用|把不同的规则分割开。
例子
1 | 匹配美国的邮政编码(美国邮编的规则是5位数字,或者用连字号间隔的9位数字): |
特别注意
因为匹配分支条件时,会从左往右地测试每个条件,如果满足某一分支,就不会执行后续的条件
所以使用分支条件时,要注意各种条件的顺序,如果将上述的代码切换位置,我们就可能会匹配到9位邮编的前5位
分组
适用场景
想要重复多个字符,如abcabcabc
知识点
可以用小括号来指定子表达式(也叫分组)
例子
1 | 匹配ip地址: |
反义
知识点
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
适用场景
想要查找不属于某个能简单定义的字符列的字符
例子
1 | 匹配不包含空格符的字符串:\S+ |
反向引用
知识点
用小括号指定一个子表达式后,匹配这个子表达式的文本可以在表达式或其他程序中作进一步的处理。
默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
同样也可以自己制定子表达式的组名,语法格式如:(?
分类 | 代码/语法 | 说明 |
---|---|---|
捕获 | (exp) | 匹配exp,并捕获文本到自动命名的组里 |
捕获 | (? |
匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp) |
捕获 | (?:exp) | 匹配exp,不捕获匹配的文本,也不给此分组分配组号 |
零宽断言 | (?=exp) | 匹配exp前面的位置 |
零宽断言 | (?<=exp) | 匹配exp后面的位置 |
零宽断言 | (?!exp) | 匹配后面跟的不是exp的位置 |
零宽断言 | (?<!exp) | 匹配前面不是exp的位置 |
注释 | (?#comment) | 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 |
适用场景
用于重复搜索前面某个分组匹配的文本
例子
1 | 匹配重复的单词如go go: |
零宽断言
适用场景
在某些内容之前或之后满足一定条件的东西
知识点
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置后面能匹配表达式exp。
1 | 匹配以ing结尾的单词的前面部分\b\w+(?=ing\b) |
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。
1 | 匹配以re开头的字母的后半部分:(?<\bre)\w+\b |
负向零宽断言
适用场景
在某些内容之前或之后不满足一定条件的东西
知识点
零宽度负预测先行断言:(?!exp),断言此位置后面不能匹配表达式exp
1 | 匹配三位数字且三位数字的后面不能是数字 |
零宽度负回顾后发断言:(?<!exp),断言此位置的前面不能匹配表达式exp
1 | 匹配前面不是小写字母的七位数字 |
注释
知识点
(?#comment)可以包含注释
例子
1 | 2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199) |
贪婪与懒惰
知识点
贪婪:当正则表达式中包含能接受重复的限定符时,通常的行为是匹配尽可能多的字符。它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
懒惰:匹配尽可能少的字符,语法:在限定符的后面加上?
1 | .*?意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复 |
代码/语法 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
特别注意
正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权——The match that begins earliest wins。