一、正则表达式基础语法
本文是慕课网上鬼斧神工之正则表达式课程的阅读笔记-2
学习正则表达式要搞清以下几个词的意义
- 界定符
- 原子
- 量词
- 边界控制
- 模式单元
1. 界定符
界定符表示一个正则表达式的开始和结束;eg:/[0-9]/;
正则表达式的本质也是一个字符串,只不过这个字符串的前后都有一个斜杠。
界定符虽然也算正则表达式语法中的一份子,但在理解的时候可以认为界定符不是正则表达式的组成部分,它只是告诉PHP的解析器,正则表达式从哪里开始到哪里结束。在PHP语言中,界定符是两个斜杠/[0-9]/,除此之外,还可以写成#[0-9]#,{[0-9]}(在PHP中,习惯不使用{},避免界定符和运算符两者相混淆)。
$pattern = ‘/[0-9]/’ 或者 #[0-9]# {[0-9]}(不推荐使用大括号);
regexpal:这是个正则表达式工具,可以实时调试正则表达式。书写正则表达式的时候不包含界定符。
2. 原子
原子是正则表达式中的最小匹配单位,通常它只是Unicode编码表中的某一个字符。
原子分为2种:
- 可见
- 不可见
可见原子:Unicode编码表中用键盘输出后肉眼可见的字符
不可见原子:Unicode编码表中用键盘输出后肉眼不可见的字符(空格,回车,tab等)
注意:
正则表达式中出现汉字时,最好将汉字转化为Unicode编码(可以使用转化工具)
patten中若有中文汉字,建议换成unicode编码,来防止由于编码格式的不同而导致的匹配失败的情况当你要匹配的标点符号正好是正则表达式运算符的时候,在符号前面加\,比如$运算符 ,用 \转义
原子的筛选方式:
符号 | 作用 |
---|---|
| | 匹配两个或多个分支选择 |
[] | 匹配方括号中的任意原子 |
[^] | 匹配除方括号外的任意字符串 |
原子集合:
符号 | 作用 |
---|---|
. | 匹配除了换行符之外的任意字符, 和[^\n]等价 |
\d | 匹配任意一个十进制数字 即[0-9] |
\D | 匹配任意一个非十进制数字 即[^0-9] |
\w | 匹配任意一个数字, 字母或下划线 [0-9a-zA-Z_] |
\W | 匹配人一个非数字, 字母或下划线[^0-9a-zA-Z_] |
\s | 匹配一个不可见的原子 即[\f\n\r\t\v] |
\S | 匹配一个可见的原子 即[^\f\n\r\t\v] |
3. 量词
符号 | 作用 |
---|---|
{n} | 表示匹配其前面的原子恰好出现n次 如:5{3} 相当于 555 |
{n,} | 表示匹配其前面的原子最少出现n次 如:[a-zA-Z]{5,}至少连续出现5次的字母如wertt |
{n,m} | 表示其前面的原子最少出现5次,最多出现m次 如:\w{5,9} |
* | 匹配0次, 1次或者多次其之前的原子 即{0,} 如:\w* |
+ | 匹配1次或多次其之前的原子 {1,} 如:\d+ |
? | 匹配0次或1次其之前的原子 {0,1} 如:_?u |
4. 边界控制和模式单元
符号 | 作用 |
---|---|
^ | 匹配字符串开始的位置 |
$ | 匹配字符串结尾的位置 |
() | 匹配其中的整体为一个原子,模式单元 |
要匹配 Dang~或者dang~目标串
之前的写法: Duang~|duang~ 或 [Dd]uang~
模式单元写法:(D|d)ang~
(expr) 捕获 expr 子模式,以 \1使用它.
所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储,缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式,每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
(?:expr) 忽略捕获的子模式.
(?=expr) 正向预查模式 expr.
(?!expr) 负向预查模式 expr.
5. 修正模式
符号 | 作用 |
---|---|
U | 懒惰模式 |
i | 忽略英文字母的大小写 |
x | 忽略空白 包括制表符和空格 |
s | 将元字符 . 匹配包括换行符在内的所有字符 |
g | 在目标数据中查找到的尽可能多的匹配 |
- 贪婪匹配: 匹配结果存在歧义的时候取长的
- 懒惰匹配; 匹配结果存在歧义的时候取短的
// 修正模式
$pattern = '/imooc.+123/U'; // 定界符后添加U为懒惰模式
$subject = 'I love imooc___123123123123123123123';
$matches = array();
preg_match($pattern, $subject, $matches);
二、常见正则表达式书写
1. 非空
.+
2. 两位小数的浮点数
\d+\.\d{2}$
因为点是正则的运算符号, 需要进行转移, 又因为只匹配两位小数, 所以要用定界符$
3. 手机号匹配
11位数字: /1[34578]\d{10}/
模式单元方法: /1(34578)\d{10}/
手机号匹配: 11位:\d{11}
第一位为1 : 1\d{10}
第二位为3/5/8/4/7 :1[34578]\d{9}或者模式单元法:1(34578)\d{9}
4. 匹配邮箱
^\w+(.\w+)*@\w+(.\w+)+$
\w表示必须以大小写字母或下划线开头
(.\w+)*表示 .xxx在@前的邮箱名中可以出现0~无限次
0次的情形:kjrb@homeway.com.cn
2次的情形:musi.ca.l@public.net
\w+表示@后面必须出现1~无穷次字母或下划线
第二个(.\w+)+表示 域名的原理同第一个(.\w+)+
但是多了一个+表示至少有一次.xxx(至少是顶级域名结尾)
最后$也控制了必须以.xxx的域名结尾的往事
5. URL匹配:
(1)http是否出现,是http还是https。即^(https?://)?。
(2)是否是二级域名? 即:(\w+.)+。
(3)顶级域名。即:[a-zA-Z]+。
故:正则表达式:^(https?://)?(\w+.)+[a-zA-Z]+$