一、基本字符
1.1、确定字符
一个最简单的正则表达式,就是一组确定字符,如hello就是一个正则表达式,它会匹配下文中的hello
/hello
直接匹配内容
1.2、范围字符
范围字符,单个范围字符只表示一个字符
字符 描述 兼容性 .
任意字符 除换行符外的任意单个字符 添加s
修饰符,可以让.
包括换行符 \w
单词字符 字母、数字、下划线任意单个字符。大写\W
表示非单词
字符 在python\w
还可以表示汉字 \d
数字 0-9任意单个数字。大写\D
表示非数字 \s
空白字符 空格、tab制表符、换行都属于空白字符。大写\S
非空白字符
1.3、自定义范围字符[]
1.3.1、任意范围[abc123]
例如小写字母
[abcdefg一直到z]
注意,这里只表示一个字母,是a~z其中的一个字母
1.3.2、区间范围[0-9]
所有小写字母简写方式如下
[a-z]
所有字母
[A-Za-z]或[A-z]
1.3.3、混合范围
所有小些字母和数字
[a-z0-9]
[A-z\d_]等同于\w
[\d\D] 所有字符 不等于. 因为多了\n换行符
1.3.4、排除范围集[^]
可以通过[]和^取反符号进行组合
[^\d]表示所有的非数字 等同与\D
[^\D8-9] 表示排除所有非数字,以及8和9。等同于 [0-7]
1.3.5、范围集中的特殊字符[.$^]
.表示任意字符,但在[.] 中它表示的是 . 字符本身。甚至是^、-、[、] 范围集本身语法,如果不是在恰当位置,也表示其字符本身。为避免混淆建议大家在范围集中匹配特殊字符时,统一加上 转义符 \。 如 [\^\.] 表示匹配 ^ 或 .
Java 中的特殊用法,例如匹配车牌号,车牌号中为了防止混淆,没有IO
[\w&&[^IO]],即匹配单词和数字并且排除掉 I 和 O
等同于[A-HJ-NP-z]
1.3.6、转义特殊符\
例如,如果要匹配^符号,使用/\^
进行匹配
二、逻辑控制指令
逻辑符 描述 |
或 如hi|hello|hellow 匹配其中一个单词即可。 ()
子表达式 用于独立计算括号中的内容。如:(张|李)建国 表示第一个字符是张或者李。 {}
数量控制 对字符或字表达式的数量范围进行限定。如:张.{1,3} 表示“张”后面只能跟1到3个任意字符。
2.1、基本逻辑控制
2.1.1、|
或
# 表示第一个字符为 a 或者 b
/a|b
等同于
[ab]
在 Unix 中的使用
由于 |
在类Unix系统中是特殊字符,当你使用grep
或 vim
进行正则搜索时,必须进行转义
grep '401\|403\|404\|500' nginx.access.log
在vim 中输入/
开始正则搜索,同样|
需要转义
/401\|403\|404|500
2.1.2、()
嵌套子表达式
与编程中的括号作用类似 如 `(1+2)*3=9` ,它们都是把一段逻辑进行拆分独立运算,再组合一起。如`(www|mvn|test).coderead.cn` 表示子域名为www、mvn、test任意一个。这里子域名就是一个**子表达式**。
会将()内的语句作为一个整体进行匹配
例如
/(http|https)://.*
就会匹配所有 http://.* 和 https://.*
子表达式支持嵌套,如:(www|mvn|test-(bj|sz|gz|sh)).coderead.cn 表示 test子域名又可继续拆分为test-bj、test-sz、test-sh、test-gz。
除此之外()
还可以表示分组和边界断言
()
与[]
的区别
# 表示第一个字符是 abc123 其中的一个
/[abc|123]
# 表示匹配 abc 或者 123
/(abc|123)
2.2、数量控制{}
逻辑符 描述 {n}
指定数量 匹配n个字符 {n,m}
指定范围 匹配n至m个字符,即至少n个,最多m个。 {n,}
n个及以上 匹配n个或者n个以上字符 *
任意个 相当于{0,} 0个或无数个 +
至少1个 相当于 {1,} ?
0或1个 相当于 {0,1}
2.2.1、{n}
指定数量
数量控制作用于字符或子表达式,已限制其数量范围。\d{6}表示必须是6位数字。请注意:一个{}仅作用于其前面的单个字符如:hi{2} 表示hii,而不是hihi。
2.2.2、{n,m}
指定范围
# 表示 2 个到 9 个字符
/\w{2,9}
2.2.3、{n,}
指定最小值
# 表示 2 个以上的字符
/\w{2,}
2.2.4、{}
作用于子表达式
2.2.5、*+?
量词简写
* 表示 {0,} 即 0 到无穷大个
+ 表示 {1,} 即 1 个以上包含 1 个
? 表示 {0,1} 即 0 到 1 个
2.2.6、?
最少化匹配(懒惰匹配)
对于一个字符串
<span>hello</span> <span>hello</span>
/<span>.*</span> 会直接匹配整个字符串,默认是最大化匹配,如果想分开匹配可以使用下面
/<span>.*?</span> 实现最小化匹配
默认匹配的原理,对于 /<span>.*</span> 正则匹配
1. <span> 会匹配字符串的<span>
2. . 会匹配除换行外的所有字符
3. * 会匹配到字符串末尾
4. </span> 正则会进行回退,直到退到与 </span> 匹配
所以默认为最大匹配
如果是增加了 ?
会回退到最先的 </span>
所以性能的话,是默认的最大化匹配最高。
总结
?表示最小化匹配,也叫懒惰匹配,只能用在量词后面,表示如果多个文本段同时满足条件,则匹配最短的。?可以用在所有量词后面,甚至是?? ,但这个量词不能是固定的值,如:hel{2}?o 这是没有意义的。因为它不存在最少和最多。