正则表达式(Regular Expression)是为了字符串模式匹配,从而实现搜索和替换功能的一种用来描述规则的表达式。
基本组成元素
- 字符:基础的计算机字符编码,常用的就是数字、英文字母。
- 元字符:即特殊字符,用来表示特殊语义的字符。
字符匹配
单个字符(一对一匹配)
最简单的正则表达式可以由简单的数字和字母组成,没有特殊的语义,纯粹就是一一对应的关系。即正则表达式被用来筛选匹配的字符只有一个。如果本来这个字符不是特殊字符,使用转移符号就会让它拥有特殊的含义。
特殊字符 | 正则表达式是 | 记忆方式 |
---|---|---|
换行符 | \n | new line |
换页符 | \f | form feed |
回车符 | \r | return |
空白符 | \s | space |
制表符 | \t | tab |
多个字符(一对多匹配)
引入集合区间和通配符实现一对多的匹配。在正则表达式里,集合的定义方式是使用中括号和元字符。即使有了集合和区间的定义方式,如果同时匹配多个字符也还是需要一一列举,这是低效的,所以在正则表达式里衍生了一批用来同时匹配多个字符的简便正则表达式。
区间匹配 | 正则表达式 | 记忆方式 |
---|---|---|
除了换行符之外的任何字符 | . | 句号,除了句子结束符 |
单个数字,[0-9] | \d | digit |
除了[0-9] | \D | not digit |
包括下划线在内的单个字符,[A-Za-z0-9_] | \w | word |
非单字字符 | \W | not word |
匹配空白字符,包括空格、制表符、换页符和换行符 | \s | space |
匹配非空白字符 | \S | not space |
循环与重复(多个字符的匹配)
同时匹配多个字符,实现多个字符的匹配,需要多次循环,重复正则规则即可,根据循环次数的多少,可以分为0次、1次、多次和特定次。
- 0|1:?
元字符?代表匹配1个字符或0个字符,。
想要匹配color和colour这两个单词,就需要同时保证u这个字符是否出现都能被匹配到,所以正则表达式为:
/colou?r/
- >=0:*
元字符*用来表示匹配0个字符或无数个字符。通常用来过滤某些可有可无的字符串。 - >=1:+
元字符+适用于要匹配同个字符出现1次或多次的情况。 - 特定次数
匹配特定重复次数用元字符大括号来给出重复匹配的设置精确的区间范围。
a匹配3次表示为:
/a{3}/
语法规则:
- -{x}:x次
- -{min,max}:介于min次和max次之间
- -{min,}:至少min次
- -{0, max}:至多max次
位置边界匹配
在长文本字符串查找过程中,需要限制查询的位置。
单词边界(\b)
单词是构成句子和文章的基本单位,一个常见的使用场景时把文章或句子中的特定单词找出来。
在句子“The cat scattered his food all over the room”中想找cat这个单词,如果使用/cat/这个正则,就会同时匹配到cat和scattered这两个单词。如果使用边界正则表达式\b,其中b是boundary的首字母。在正则引擎里它其实匹配的是能构成单词的字符(\w)和不能构成单词的字符(\W)中间的那个位置。
/\bcat\b/
字符串边界
边界和标志 | 正则表达式 | 记忆方式 |
---|---|---|
单词边界 | \b | boundary |
非单词边界 | \B | not boundary |
字符串开头 | ^ \hat{} ^ | |
字符串结尾 | $ | |
多行模式 | m | multiple |
忽略大小写 | i | ignore |
全局模式 | g | global |
子表达式
通过嵌套递归和自身引用可以让正则发挥更强大的功能。从简单到复杂的正则表达式演变通常要采用分组、回溯引用和逻辑处理的思想。利用这三种规则,可以推演出无限复杂的正则表达式。
分组
小括号元字符所包含的正则表达式被分为一组,每一个分组都是一个子表达式,它是构成高级正则表达式的基础,如果只是使用简单的(regex)匹配语法本质上和不分组是一样的,如果要发挥它强大的作用,需要结合回溯引用方式。
回溯引用
回溯引用(backreference)指的是模式的后面部分引用前面已经匹配到的子字符串。回溯引用的语法\1表示引用第一个子表达式,\0表示整个表达式。
匹配两个连续相同的单词
Hello what what is the first thing, and I am am 007.
\b(\w+)\s\1
前向查找
前向查找(lookahead)是用来限制后缀的。凡是以(?=regex)包含的子表达式在匹配过程中都胡用来限制前面的表达式的匹配。
happy happily
- 获得happ开头的副词:happ(?=ily)
- 过滤掉以happ开头的副词:happ(?!ily)
后向查找
后向查找是前向查找的反向操作,后向查找(lookbehind)是通过指定一个子表达式,然后从符合这个子表达式的位置出发开始查找符合规则的字符串。
apple people
只想找到apple的ple
- 方法一:/(?<=app)ple/
- 方法二:/(?<!peo)ple
逻辑处理
逻辑关系 | 正则元字符 |
---|---|
与 | 默认都是与的关系 |
非 | [ ^ \hat{} ^ regex]( ^ \hat{} ^必须与[]一起使用才表示非)和! |
或 | ∣ \mid ∣ |
【参考资料】
正则表达式不要背