正则表达式
php 正则表达式学习笔记
什么是正则表达式
正则表达式(Regular Expressions(Perl-Compatible)),就是一个匹配的模式
正则表达本身就是一个字符串
正则表达式要在对应的函数中使用
在 PHP 中有两套正则表达式函数库,两者功能相似,只是执行效率略有差异
一套由 PCRE 库提供的使用preg_为前缀命名的函数
一套由 POSIX 扩展提供的,使用以ereg_为前缀的函数
注意
PCRE 来源于 Perl 语言符号
PCRE 语法支持更多特性比 POSIX 跟强大
正则语法
$reg = "/a\d/i"
定界符号,可以使用多种,常用为//
原子:最小的匹配单位 \a\(要放在定界符中)
元字符:不能单独使用,修饰原子,是用来扩展原子功能和限制/\d/(要放在定界符中)
模式修正符号:修正,对模式(正则的修正)/a/i(要放在定界符外)
正则表达式中的原子
原子是正则表达式的最小单位,一个表达式至少由一个原子组成
原子是由所有那些未被显示指定为元字符的 打印字符和非打印字符组成,具体分为 5 类。(所有的字符都是原子)
普通字符作为原子:a-z A-Z 0-9等
一些特殊字符和转移后元字符可作为原子:
所有的标点符号,但语句特殊意义的符号需要转义后才可做为原子,如 \"\'\*\+\?\.等
一些非打印字符作为原子:如\f\n\r\t\cx
使用"通用字符类型" 作为原子: 如:\d\D\w\W\s\S
自定义的原子表([])作为原子:如:'/[apj]sp/' '/[^apj]sp/'
普通字符作为原子
打印字符a-z A-Z 0-9 !@#$%^&*()...
非打印字符\n...
$str = "this is a ^ test ";
$reg = "/\^/";
if (preg_match($reg, $str, $arr)) {
echo "正则表达式{$reg}和{$str}匹配成功!\n";
print_r($arr);
} else {
echo "匹配失败";
}
正则表达式/\^/和this is a ^ test 匹配成功!
Array
(
[0] => ^
)
'\':转义符号:
一些特殊字符和转移后元字符可作为原子
可以将有意义的符号转成没有意义的原子,例如/\^/
可以将没有意义的字符转成有意义的原子,例如/\t/(tab 键)
a-z A-Z 0-9 所有这些没有意义的字符,加上转义也没有意义的有都是可以加可不加的
除了a-z A-Z 0-9这些符号不需要转移,其他符号使用时最好转义,大多数特殊符号有特别意义
使用"通用字符类型"
\d
代表任意一个数字
\D
代表任意一个非数字
# /\d/
$str = "this is a 123 test 11";
// 匹配所有数字
$reg = "/\d/";
------------------------------------------
正则表达式/\d/和this is a 123 test 11匹配成功!
Array
(
[0] => Array
(
[0] => 1
[1] => 2
...
)
)
# /\D/
$str = "this is a 123 test 11";
// 匹配所有数字
$reg = "/\D/";
------------------------------------------
正则表达式/\D/和this is a 123 test 11匹配成功!
Array
(
[0] => Array
(
[0] => t
[3] => s
[4] =>
[5] => i
...
)
)
\w
代表任意一个字 a-z A-Z 0-9 _
\W
代表任意一个非字 除了 a-z A-Z 0-9 _之外的所有字符
# /\w/
$str = "!@$@%%^%$@____";
// 匹配所有字
$reg = "/\w/";
------------------------------------
正则表达式/\w/和!@$@%%^%$@____匹配成功!
Array
(
[0] => Array
(
[0] => _
[1] => _
...
)
)
# \/W\
正则表达式/\W/和!@$@%%^%$@____匹配成功!
Array
(
[0] => Array
(
[0] => !
[1] => @
[2] => $
[3] => @
...
)
)
\s
代表空白
\S
代表任意一个非空白
# /\s/
$str = "qw
we rt";
----------
Array
(
[0] => Array
(
[0] =>
[1] =>
[2] =>
[3] =>
)
)
#/\S/
正则表达式/\S/和qw
we rt匹配成功!
Array
(
[0] => Array
(
[0] => q
[1] => w
[2] => w
[3] => e
[4] => r
[5] => t
)
自定义的原子表
使用[]来指定
# [469]
正则表达式/[469]/和1243456768909匹配成功!
Array
(
[0] => Array
(
[0] => 4
[1] => 4
[2] => 6
[3] => 6
[4] => 9
[5] => 9
)
)
可以指定范围用'-'表示
正则表达式/[1-5]/和1243456768909匹配成功!
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 3
[4] => 4
[5] => 5
)
)
非^
匹配所有的非数字
正则表达式/[^1-4]/和ass2423匹配成功!
Array
(
[0] => Array
(
[0] => a
[1] => s
[2] => s
)
)
.点
代表所有
注
正则表达式中的常用非打印字符
原子字符
含义描 述
\cx
匹配由 x 指明的控制字符,如cM 匹配一个 Control-M 或返回车符,x 必须为 a-z 或 A-Z 之一
\f
匹配一个换页符,等价与x0x 或cL
\n
匹配一个换行符,等价与x0a 或cJ
\r
匹配一个回车符,等价与x0d 或cM
\t
匹配一个制表符,等价与x09 或cI
\v
匹配一个垂直制表符,等价与x0b 或cK
...
...
正则表达式中的元字符
不能在正则表达式单独使用,用来修饰原子
'*'用来修饰前面的原子可以出现 0 个 1 个或多个
# /go*gle/
正则表达式/go*gle/和this gggggoogle is a test 匹配成功!
Array
(
[0] => Array
(
[0] => google
)
)
'+' 匹配 1 次或多次其前的原子(前面原子至少出现一次)
正则表达式/g+oogle/和this gggggoogle is a test 匹配成功!
Array
(
[0] => Array
(
[0] => gggggoogle
)
)
'?' 匹配 1 次或多次其前的原子(前面原子不能出现多次)
#正则表达式/go?gle/和this gogle is a test 匹配成功!
Array
(
[0] => Array
(
[0] => gogle
)
{n} 表示其前面的原子恰好出现 n 次
# 正则表达式/go{2}gle/和this google is a test 匹配成功!
Array
(
[0] => Array
(
[0] => google
)
)
{n,} 表示其前面的原子出现不小于 n
# 正则表达式/go{2,}gle/和this google is a test 匹配成功!
Array
(
[0] => Array
(
[0] => google
)
)
{n,m} 表示其前面的原子至少出现 n 次,最多出现 m
# 正则表达式/go{1,3}gle/和this google is a test 匹配成功!
Array
(
[0] => Array
(
[0] => google
)
)
()
改变优先级别
将小原子改变成大原子
子模式,整个表达式是一个大的模式,小括号中是每个独立的子模式
反向引用
正则表达式/orac(le|my)/和this oracmysql is a test 匹配成功!
Array
(
[0] => Array
(
[0] => oracmy
)
[1] => Array
(
[0] => my
)
)
正则表达式/orac(mysql)*/和this oracmysql is a mysql 匹配成功!
Array
(
[0] => Array
(
[0] => oracmysql
)
[1] => Array
(
[0] => mysql
)
)
正则表达式/(http|ftp):\/\/\www(.*)?\.(com|net)/和this http://www.baidu.com oracmysql ftp://www.exp.net is a mysql 匹配成功!
Array
(
[0] => Array
(
[0] => http://www.baidu.com oracmysql ftp://www.exp.net
)
[1] => Array
(
[0] => http
)
[2] => Array
(
[0] => .baidu.com oracmysql ftp://www.exp
)
[3] => Array
(
[0] => net
)
)
正则表达式/\d{4}(-|\/)\d{2}\1\d{2}/和this 2020-03-06 2020/03/06 匹配成功!
Array
(
[0] => Array
(
[0] => 2020-03-06
[1] => 2020/03/06
)
[1] => Array
(
[0] => -
[1] => /
)
)
元字符表
元字符
含义描述
*
匹配 0 次,1 次或多次其前的原子
+
匹配 1 次或多次其前的原子
?
匹配 0 次或 1 次其前的原子
!
匹配两个或多个分支选择
{n}
表示其前面的原子恰好出现 n 次
{n,}
表示其前面的原子出现不小于 n 次
{n,m}
表示其前面的原子至少出现 n 次,最多出现 m 次
^或、A
匹配输入字符串的开始位置(或在多模式下行的开头,既紧随一个换行符之后)
\$或\Z
匹配输入字符串的结束位置(或在多模式下行的开头,既紧随一个换行符之后)
\b
匹配单词的边界
\B
匹配除单词边界以外的部分
()
匹配整体为一个原子,即模式单元,可以理解为由多个单原子组成的大原子
模式修正符号(单个字符)
模式修正符号要写在定界符号之外(右边)
例:
"/go*gle/i"
模式修正符号 ,一个字符就是一个功能
作用:
模式修正符号可以修正正则表达式的解释,扩充了正则表达式的功能
i:修正正则表达式不区分大小写 (默认是区分大小写的)
正则表达式/test/i和this is a Test匹配成功!
Array
(
[0] => Array
(
[0] => Test
)
)
m 把多行视为多行(默认正则把多行视为一行)
正则表达式/^is/m和this
is a Test匹配成功!
Array
(
[0] => Array
(
[0] => is
)
)
s修正正则表达式中的.可以匹配换行符号(默认.不可以匹配换行符)
正则表达式/Te.*st/s和this is a Te
st匹配成功!
Array
(
[0] => Array
(
[0] => Te
st
)
)
s修正正则表达式,可以省略空白
正则表达式/web server/ix和this is a WebServer匹配成功!
Array
(
[0] => Array
(
[0] => WebServer
)
)
U(.* ,+)正则表达式比较贪婪 U 可以取消贪婪模式(不经常使用一般用(.*?))
正则表达式的编写
正则表达式就是一种语言,要学会开放思想
列需求
编写匹配 url 正则
$str = "
这是http://www.example.com网站
这是http://www.xxx.net/index.php网站
这是http://www.example.cn/php网站
这是http://www.demo.org/login.php?user=aaa网站
这是https://www.test.top网站
这是https://news.baidu.top网站
这是ftp://news.baidu.top网站
";
$reg = "/(https?|ftps?):\/\/(.*?).(.*?).(com|net|org|cn|top)([\w\.\/\=\?\&]*)?/";
preg_match_all($reg, $str, $arr);
print_r($arr);
编写匹配 email 正则
$str = "
这是lqjxm666@163.com邮箱
这是muxi-Kf4@gmail.com邮箱
这是muxi_k_ing@163.com邮箱
这是muxi_k@xx-xx.com邮箱
";
$reg = "/\w+([-+]\w+)*@\w+(-.\w+)*\.\w+/i";
preg_match_all($reg, $str, $arr);
print_r($arr);
正则表达式使用
分割、匹配、查找、替换
字符串处理函数(处理快,但有一些做不到)
正则表达式函数(功能强大,但效率低)
注意:能用字符串处理函数处理的字符串,就不用正则处理
匹配查找:
strstr()
strpos()
substr()
正则匹配
preg_match()
preg_match_all()
preg_grep()
字符串分割
explode()
implode()
join()
正则分割
preg_split()
字符串替换
str_replace()
正则替换
preg_replace()