正则表达式学习整理(一)
0. 简介
下雨天在家,看看资料,再熟悉下正则表达式, 参考的文档是 正则表达式入门
本次主要是记录正则表达式相关的元字符、字符转义、重复、字符类、分枝条件、分组、反义、反向引用、零宽断言、负向零宽断言、贪婪与懒惰、处理选项等
1. 元字符
元字符分几部分,主要包括用来表示字符的,用来表示位置的,用来表示重复次数的.
字符 | 说明 |
---|---|
. | 匹配除换行以外的任意字符 |
\w | 匹配字符数字下划线汉字 |
\s | 匹配空白字符 |
\d | 匹配数字 |
\b | 匹配单词的开始和结束 |
^ | 匹配行内字符串的开始 |
$ | 匹配行内字符串的结束 |
2. 字符转义
对于元字符本身,如果想单纯的匹配元字符本身,需要用 \
对元字符进行转义, 比如\.
匹配小数点, \*
匹配星号(*)
3. 重复
代码和语法|说明 ——–|——
-
重复零次或者更多次 ? 重复零次或者一次 -
重复一次或者更多次 {n} 重复n次 {m,} 重复m,或者大于m次 {m,n} 重复m到n次之间
几个例子:
- \d+ 匹配1个或者多个数字,等价于 \d{1,}
- [a-b]{1,3} 匹配1到3个小写字母
4. 字符类
要查找元字符可以表示的字符类是很简单的,比如\d 表示数字字符集。 对于查找没有预定义的字符集,需要用方括号括起来,表示需要匹配的字符集。
如: [aeiou] 表示匹配所有的元字母; [0-5] 表示匹配0到5中任一数字; [,!\?] 匹配标点符号(,!?)
5. 分支条件
linux 命令grep 如果想要查找多个字符串, 可以用-e 选项来指定,也可以用正则表达式的分支条件来实现 grep -e hello -e world
等级于 grep -E "hello|world"
.
正则表达式的分支条件是通过 |
来实现的, 就是用 |
把不同的多个匹配规则分割开, 只要满足一个规则就是匹配成功。
6. 分组
在前面\d+
可以实现对单个字符的重复次数的匹配, 如何实现匹配多个字符的重复次数呢? 可以通过小括号()
来指定子表达式规则(也成为分组), 然后就可以指定这个子表达式的重复次数了。
几个例子:
- (\d{1,3}\.){3}\d{1,3} 可以简单的匹配一个ip地址, 如 113.44.60.124, 只是能简单的匹配,没能做到判断ip是否合法
7. 反义元字符
代码语法 | 说明 |
---|---|
\W | 匹配任意不是字母数字下划线汉字的字符 |
\S | 匹配任意不是空白字符的字符 |
\D | 匹配任意不是数字的字符 |
\B | 匹配任意不是单词开始或者结束的位置 |
[\^x] | 匹配任意不是x的字符 |
[\^aeiou] | 匹配任意不是 a e i o u 这几个字符的字符 |
如: \S+ 匹配不包含空格的字符串; <a[^>]+> 匹配用<> 括起来并且以a开头的字符串
8. 反向引用
通过小括号匹配一个子表达式分组后,可以在匹配之后用来做一些处理, 每一个匹配到的子表达式分组都对应一个可以用来反向引用的分组号, 分组号的规则是: 从左向右依照左边括号出现的次序来分配分组号,第一次出现的左小括号对应的分组的分组号是1, 以此类推2,3,….。
反向引用:可以用来匹配之前某个分组匹配的字符, 例如, 通过 \1
代表分组1 匹配的字符。
例子: \b(\w+)\b\s+\1\b
匹配连续出现的单词, 如 go go
, hello hello
等
对于子表达式分组的分组号除了默认的数字编号表示外,还可以为每个子表达式自定义分组名.
**指定子表达式分组名的方式为: (?<word>\w+)
** , 还可以把尖括号换成'
(?'word'\w+)
这样就把分组名设定为了word
反向引用这个分组匹配的字符串通过\k<word>
。
使用语法 \k<名称> 在同一正则表达式中引用匹配的子表达式,其中名称是捕获子表达式的名称。名称>
常用的分组语法如下表:
分类 | 代码语法 | 说明 |
---|---|---|
捕获 | (exp) | 匹配exp, 并捕获文本到自动命名的组里面 |
捕获 | (?<name>exp) | 匹配exp, 并捕获文本到名称为name的组里面 |
捕获 | (?:exp) | 匹配exp,不捕获文本,也不为文本自动分配组名称 |
零点断言 | (?=exp) | 匹配exp前面的位置 |
零点断言 | (?<=exp) | 匹配exp后面的位置 |
零点断言 | (?!exp) | 匹配后面跟的不是exp的位置 |
零点断言 | (?<!exp) | 匹配前面不是exp的位置 |
注释 | (?#comment) | 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读 |
(exp) 和 (?<name>exp) 这两种分组的语法我们已经学习到了, 第三个(?:exp) 只匹配不捕获的,接下来介绍下使用场景
9. 零宽断言
零宽断言用来查找某些内容之前或者之后的字符, 就像\b, ^ 和 $ 三个元字符一样,用来指定一个位置,这个位置应该满足一定的条件, 因为只是匹配一个位置,所以叫零宽断言
-
(?=exp) 匹配exp之前的位置, 被匹配到的字符串的后面紧跟表达式exp. 比如:
\b\w(?=ing\b)
匹配以ing结尾的单词的ing前面的部分, 如果在I am singing while you are dancing
进行匹配会匹配到sing 和 danc. -
(?<=exp) 匹配exp之后的位置,被匹配到的字符的前面是exp表达式代表的字符, 比如:
(?<=\bre)\w\b
, 匹配re开头的单词re后面部分的字符串,匹配reading a book
时,会匹配到ading