原子
原子,也叫原子字符,是正规表达式函数操作的对象。
学习之前先搞清三个概念:
1. 原子是正则表达式的最小单位;
2. 每个正则模式中,至少要包含一个原子;
3. 原子必须由可打印和非打印字符组成。
* * * * * ## 原子的组成: >[info] 大体上,可以将原子字符分为5类:
2. 每个正则模式中,至少要包含一个原子;
3. 原子必须由可打印和非打印字符组成。
序号 | 原子 | 说明 |
---|---|---|
1 | 普通字符 | 可打印字符,如大小写字母、数字等 |
2 | 特殊字符或元字符 | 因为这类字符在正则表达式中有特殊含义,必须转义 |
3 | 非打印字符 | 即存在但不可显示字符,如回车、换行、换页,制表符等 |
4 | 通配字符 | 也叫:通用字符或者'类字符',即一个原子匹配一类字符 |
5 | 自定义字符 | 可以是一个,也可以是集合,用方括号'[ ]'包起来 |
下面我们详细介绍一下这五类原子:
1. 普通字符做原子:
普通字符:就是我们可以在屏幕上看见的字符,如字母、数字等。
序号 | 原子字符 | 说明 |
---|---|---|
1 | 小写字母/'a-z'
|
/php/ , /abc/,/google/ |
2 | 大写字母/'A-Z'
|
/THINKPHP/, /CHINA/ |
3 | 数字/'0-9'
|
/3.14/, /18/ |
一个原子匹配目标字符串中的一个字符,逐一对应。
- 实例:
<?php echo preg_match('/php/', 'thinkphp') ? '匹配成功<br />' : '匹配失败<br />'; //匹配成功 echo preg_match('/PHP/', 'ThinkPHP') ? '匹配成功<br />' : '匹配失败<br />'; //匹配成功 echo preg_match('/5/', 'ThinkPHP5') ? '匹配成功<br />' : '匹配失败<br />'; //匹配成功
2. 特殊字符和元字符做原子:
元字符在正则中有特殊用途,是用来修饰原子的,下节课会详细讨论,这里你只需要知道,元字符做原子时,不能直接使用,必须转义,使其变成普通原子字符。
序号 | 原子字符 | 说明 |
---|---|---|
1 | 元字符 | '\.', '\+', '\?', '\$', '\*' |
2 | 特殊字符 |
'\<br \/>' 匹配是否出现‘<br />’ 标记 |
- 实例:
<?php echo preg_match('/\./', 'ThinkPHP5.0') ? '匹配成功<br />' : '匹配失败<br />'; //匹配成功 //<br /> 需要3次转义:2个尖括号'<'和'>',1个反斜杠'/' echo preg_match('/\<br\/\>/', 'ThinkPHP5<br/>') ? '匹配成功<br />' : '匹配失败<br />';//匹配成功
3. 非打印字符做原子:
非打印字符,也叫不可见字符,主要是一年格式控制符。
- 最常用的有四个:
序号 | 原子字符 | 说明 |
---|---|---|
1 | '\n' |
匹配一个换行符,等价于:'\x0a'
|
2 | '\r' |
匹配一个回车符,等价于:'\x0d'
|
3 | '\f' |
匹配一个换页符,等价于:'\x0c'
|
4 | '\t' |
匹配一个制表符,等价于:'\x09'
|
5 | '\v' |
匹配一个垂直制表符,等价于:'\x0b'
|
- 实例:
<?php echo preg_match('/\r\n/', "ThinkPHP5.0\r\n") ? '匹配成功<br />' : '匹配失败<br />';//匹配成功
代码分析:
- 目标字符串
"ThinkPHP5.0\r\n"
必须要用双引号""包起来,因为只有双引号里的字符串才可以解析所有转义字符; - 单引号内只解析2种:单引号自身
'\'
和 转义符自身\\
不可见,不代表不存在。不可见字符仅仅是无法用肉眼看见,但可以感知存在。
4. 通配字符做原子:
通配字符,也叫通用字符、类字符。我个人觉得叫:类字符更贴切~~
序号 | 原子字符 | 说明 |
---|---|---|
1 | '\d' |
匹配任意一个十进制数,等价于:[0-9]
|
2 | '\D' |
匹配任意一个除十进制以外的字符,等价于:[^0-9]
|
3 | \w |
匹配任意一个字母/数字/下划线字符,等价于:[a-zA-Z0-9_]
|
4 | \W |
匹配任意一个除字母/数字/下划线之外的字符,等价于:[a-zA-Z0-9_]
|
5 | \s |
匹配任意一个空白字符(非打印),等价于:[\f\n\r\t\v]
|
6 | \S |
匹配任意一个除空白字符以外的字符,等价于:[^\f\n\r\t\v]
|
####类原子匹配的是一类字符(字符集合),不再是一个字符~~
- 实例:
<?php //匹配十进制数0-9,等价于:[0-9] echo preg_match('/\d\./', "3.1415926") ? '匹配成功<br />' : '匹配失败<br />';//匹配成功 //匹配大小写字母和下划线,等价于:[a-zA-z0-9_] echo preg_match('/\w/', "ThinkPHP5.0") ? '匹配成功<br />' : '匹配失败<br />';//匹配成功 //匹配字符串中的空格符,等价于:[\r\n\r\t\v] echo preg_match('/\s/', "Think PHP5.0") ? '匹配成功<br />' : '匹配失败<br />';//匹配成功
5. 自定义原子:
尽管上面所说的原子已经很丰富了,但不能穷举全部原子类型,如果上面不符合要求,就需要我们自己动手,创建自己的原子啦!
1. 自定义原子是一个集合,可以匹配一个,也可以匹配多个字符;
2. 自定义原子列表,使用方括号'[ ]',括号内所有原子地位平等,顺序可随意调整;
3. 自定义原子列表中,可以使用排除符号'^',过滤掉不符合要求字符。
2. 自定义原子列表,使用方括号'[ ]',括号内所有原子地位平等,顺序可随意调整;
3. 自定义原子列表中,可以使用排除符号'^',过滤掉不符合要求字符。
序号 | 原子 | 说明 |
---|---|---|
1 | [单个字符列表] |
如:'\[AJ]SP\' ,表示:ASP和JSP,任选一个做为原子 |
2 | [^单个字符列表] |
'^' :表示取反,如 '\[^AJ]SP\' ,表示:除ASP和JSP之外,任选一个做为原子 |
3 | [a-zA-Z0-9_] |
如果原子集合中某类字符是连续的,可以用'-' 符号连接起始字符,表示字符区间 |
- 实例:
<?php //匹配十进制数字: \d echo preg_match('/[0-9]/', "3.1415926") ? '匹配成功<br />' : '匹配失败<br />'; //匹配大小写字母和十进制数字 echo preg_match('/[a-zA-Z0-9]/', "ThinkPHP5.0") ? '匹配成功<br />' : '匹配失败<br />'; //匹配非打印字符(即不可见字符) echo preg_match('/[\f\n\r\t\v]/', "Think PHP5.0") ? '匹配成功<br />' : '匹配失败<br />'; //匹配 ASP 或者 JSP,[]内的元素是平级关系,只要一个满足要求就匹配成功 echo preg_match('/[AJ]SP/', "ASP,JSP,PHP") ? '匹配成功<br />' : '匹配失败<br />'; //与上面相反,除了ASP或JSP外的字符串,如:PSP,符合条件,匹配成功 echo preg_match('/[^AJ]SP/', "ASP,JSP,PSP") ? '匹配成功<br />' : '匹配失败<br />';
4-2. 元字符
元字符是修饰原子字符的,可以理解为原子的定语或限定条件
- 举个生活中的小例子:戴帽子的男生
- 其中【戴帽子的】就是【元字符】;
- 那个【男生】,就是【原子】。
- 注意二点:
- 元字符不允许单独使用,必须配合原子,共同工作;
- 如果原子中包括元字符,必须在元字符加
'\'
进行转义。
元字符种类(共15个)
元字符尽管看上去很多,其实不少是成对出现,不难记忆,别被吓住了~
序号 | 元字符 | 说明 | 举例 |
---|---|---|---|
1 | * | 匹配0次、1次或多次前面原子,等价于{0,}
|
'/Go*gle/' |
2 | + | 匹配1次或多次前面原子,等价于{1,}
|
'/Go+gle/' |
3 | ? | 匹配0次或1次前面原子,等价于{0,1}
|
'/Go?gle/' |
4 | . | 匹配除换行符之外的任意一个字符 | '/Go.gle/' |
5 | | | 匹配2个或多个分支 | /Google\|Baidu/ |
6 | {n} | 表示前面原子出现n次 | /Go{2}gle/ |
7 | {n,} | 表示前面原子出现不少于n次 | /Go{2,}gle/ |
8 | {n,m} | 表示前面原子至少出现n次,最多出现m次 | /Go{2,5}gle/ |
9 | ^ | 匹配字符串开始位置 | /^php/ |
10 | $ | 匹配字符串开始位置 | /php$/ |
11 | \b | 匹配单词边界 | /\bphp/ |
12 | \B | 匹配除单词边界以外的部分 | /\Bphp/ |
13 | [ ] | 匹配方括号内指定的任意一个原子 | /[aj]sp/ |
14 | [^ ] | 匹配除方括号内指定原子以外的任意一个原子 | /[^aj]sp/ |
15 | ( ) | 匹配其整体为一个原子[模式单元],即多个原子组成的大原子 | /(Think)+PHP/ |
模式匹配优先级问题:
优先级 | 元字符 | 描述 |
---|---|---|
1 | \ | 转义字符 |
2 | ( ),(?:),(?=),[ ] | 模式单元与原子表 |
3 | *,+,?,{n},{n,},{n,m} | 重复匹配 |
4 | ^,$,\b,\B | 边界匹配 |
5 | | | 模式选择 |
实例演示:
代码说明,都写在注释中了
<?php
//*匹配前面0次,1次或多次前面原子
echo preg_match('/Go*gle/', 'Ggle') ? '匹配成功<br />' : '匹配失败<br />';
//?匹配0个或1个原子
echo preg_match('/Go?gle/', 'Gogle') ? '匹配成功<br />' : '匹配失败<br />';
//+匹配1个或多个原子
echo preg_match('/Go+gle/', 'Google') ? '匹配成功<br />' : '匹配失败<br />';
//.匹配G和g之间的任意一个字符
echo preg_match('/G.g/', 'Gogle') ? '匹配成功<br />' : '匹配失败<br />';
// | 匹配多个分支
echo preg_match('/google|baidu/', 'baidu') ? '匹配成功<br />' : '匹配失败<br />';
//^设置开头$设置结尾,精确匹配
echo preg_match('/^google$/', 'google') ? '匹配成功<br />' : '匹配失败<br />';
//{n} n表示前面原子出现的次数
echo preg_match('/go{2}gle/', 'google') ? '匹配成功<br />' : '匹配失败<br />';
//{n,} n表示前面原子至少要出现的次数,本例中,字符’o‘至少要出现2次
echo preg_match('/go{2,}gle/', 'gooogle') ? '匹配成功<br />' : '匹配失败<br />';
//{n,m} n表示前面原子至少要出现的次数,m表示最多出现次数,本例中,字符’o‘至少要出现2次,最多5次
echo preg_match('/go{2,5}gle/', 'gooooogle') ? '匹配成功<br />' : '匹配失败<br />';
// \b匹配单词边界,本例 ThinkPHP右边为边界不应再有内容
echo preg_match('/PHP\b/', 'ThinkPHP 5.0') ? '匹配成功<br />' : '匹配失败<br />';
// \B匹配除单词边界以外部分,本例 Think PHP右边不能有边界,左边必须要有边界
echo preg_match('/\bPHP\B/', 'Think PHP5.0') ? '匹配成功<br />' : '匹配失败<br />';
4-3:模式修正符
修正符作用于整个正则表达式,要注意以下几点:
- 模式修正符要写在正则表达式定界符(右边'/')之外;
- 模式修正符调整正则表达式的解析,扩展正则表达式的功能和处理能力;
- 可以将多个模式修正符同时使用,以达到更好的控制功能。
常用模式修正符:
序号 | 模式修正符 | 说明 |
---|---|---|
1 | i | 模式匹配时,忽略大小写 |
2 | m | 将字符串视为多行,每行以^开头$结尾 |
3 | s | 元字符'.'可匹配换行符,此时换行符失效,多行视为单行 |
4 | x | 忽略模式字符串中的空白字符,除非已转义 |
5 | e | 仅用在preg_replace()中,替换字符串对逆向引用做正常替换,用其结果来搜索 |
6 | U | 反转匹配数量的值使其不是默认的重复,而变成在后面加上'?'才变得重复 |
7 | D | 模式中$符号仅匹配目标字符串的结尾,如有m修正符,则忽略 |