正则表达式
正则表达式是描述字符排列和匹配模式的一种语法规则,它主要用于字符串的分割,匹配,查找,替换等操作。在PHP中正则表达式一般是由正规字符和一些特殊字符(类似于通配符)联合构成的一个文本模式的程序性描述。
PHP中正则表达式有三个作用。
- 匹配常常用于从字符串中析取信息
- 用新文本代替匹配文本
- 将一组字符串拆分为一组更小的信息块
正则表达式的组成:
- 定界符
- 原子
- 元字符
- 模式修正符
如下例匹配超链接:
'/<a.*?(?:|\\t|\\r|\\n)?href=[\"]?(.+?)[\"]?(?:(?:|\\t|\\r|\\n)+.*?)?>(.+?)<\/a.*?>/sim'
//定界符:两个斜线”/”。
//原子:用到了< a href = ‘ “ / >等普通字符和\t \r \n等转义字符
//元字符:使用了 [] () | . ? * + 等具有特殊含义的字符
//模式修正符:是在定界符最后一个斜线之后的三个字符: s i m
定界符
作为定界符常使用正斜线“/”,如“/apple/”。用户只要把需要匹配的模式内容放入定界符之间即可。作为定界的字符也不仅仅局限于“/”。除了字母、数字和反斜线“\”以外的任何字符都可以作为定界符,像“#”、“|”、“!”等都可以的。
/<\/\w+>/ //使用正斜线作为定界符合法
|(\d{3})-\d+|Sm //使用竖线”|”作为定界符合法
!^(?i)php[34]! //使用竖线”!”作为定界符合法
{^\s+(\s+)?$} //使用竖线”}”作为定界符合法
/href=‘(.*)’ //非法定界符,缺少结束定界符
1-\d3-\d3-\d4| //非法定界符,缺少其实定界符
原子
原子是正则表达式的最基本的组成单元,而且在每个模式中最少要少包含一个原子。原子是由所有那些未显示指定为元字符的打印和非打印字符组成,具体分为5类。
1.普通字符作为原子: 如 a~z、A~Z、0~9 等
2.一些特殊字符和转义后元字符作为原子:所有标点符号,但语句特殊意义的符号需要转义后才可作为原子,如:\” \’ * + \? . 等
3.一些非打印字符作为原子: 如:\f \n \r \t \v \cx
4.使用“通用字符类型”作为原子:如:\d \D \w \W \s \S
5.自定义原子表([])作为原子:如:’/[apj]sp/’ ’/[^apj]sp/’
正则表达式中常用的非打印字符:
原子字符 | 含义描述 |
---|---|
\cx | 匹配由x指明的控制字符。如\cM匹配一个Control-M或回车符。x的值必须为A~Z或a~z之一。 |
\f | 匹配一个换页符。等价于 \x0c或\cL |
\n | 匹配一个换行符。等价于 \x0a或\cJ |
\r | 匹配一个回车符。等价于 \x0d或\cM |
\t | 匹配一个制表符。等价于 \x09或\cI |
\v | 匹配一个垂直制表符。等价于 \x0b或\cK |
正则表达式中常用的通用字符:
原子字符 | 含义描述 |
---|---|
\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] |
自定义原子表(“[ ]”)
中括号中的任意一个字符,例如:
[13579] :表示匹配字符串中的1,3,5,7,9。
[^a-zA-Z] : ^匹配除了列表中的任意字符。
正则表达式中的点(”.”)
默认情况下,点(.)能代表除换行符以外的任意原子。在加上模式修正符s以后能代表所有原子。
元字符
元字符: 不能在正则表达式中单独使用, 用来修饰原子的。常用的元字符:
元字符 | 含义描述 |
---|---|
* | 匹配0次、1次或多次其前的原子 |
+ | 匹配1次或多次其前的原子 |
? | 匹配0次或1次其前的原子 |
| | 匹配两个或多个分支选择 |
{m} | 表示其前面的原子恰好出现m次 |
{m,n} | 表示其前面的原子至少出现m次,最多出现n次 |
{m,} | 表示其前面的原子出现不小于m次 |
^或\A | 匹配输入字符串的开始位置(或在多行模式下行的开头,即紧随一个换行符之后) |
$或\S | 匹配输入字符串的结束位置(或在多行模式下行的结尾,即紧随一个换行符之前) |
\b | 匹配单词的边界 |
\B | 匹配除单词边界以外的部分 |
( ) | 匹配其整体为一个原子,即模式单元。可以理解为由多个单个原子组成的大原子 |
正则表达式中的小括号()的作用
第一个作用: 改变优先级别
function p_match($reg,$str){
if(preg_match($reg,$str,$arr)){
echo "match the reg!";
}else{
echo "no match!";
}
}
$str = "this is a test code";
$reg = "/test|code/";
p_match($reg,$str);
//结果为: match the reg!
在正则表达式中 “或 |” 的优先级最低 ,所以上面的正则表达式是匹配”test”或是”code” ,而不是竖线两边的”t”和“c”,但是通过添加 括号()可以改变这种优先级的顺序。
$str = "this is a test code";
$reg = "/tes(t|c)ode/";
p_match($reg,$str); // no match!
$str = "this is a testode";
p_match($reg,$str); // match the reg!
$str = "this is a tescode";
p_match($reg,$str);// match the reg!
第二个用用: 将小原子,变成大原子
$str = "this is a test code";
$reg = "/code/";
p_match($reg,$str); // match the reg!
以上正则是匹配一个code 字符串,通过括号可以变成一个大原子
$str = "this is a test code";
$reg = "/cod(e)*/";
p_match($reg,$str); // match the reg!
可以匹配code后面接任意多个’e’字符的字符串。
$str = "this is a test codeeeeeeee";
$reg = "/cod(e)*/";
p_match($reg,$str); // match the reg!
第三个作用: 子模式, 整个表达式是一个大的模式, 小括号中是每个独立的子模式
例如匹配一个域名:
$str = "http://www.opentip.com";
$reg = "/http\:\/\/.*\.com/s";
if(preg_match($reg,$str,$arr)){
echo "match the reg!"."\n";
echo "result:\n";
print_r($arr);
}else{
echo "no match!";
}
//match the reg!
//result:
//Array([0] => http://www.opentip.com)
当需要在域名中匹配协议,主机时可以通过添加括号构成子模式来完成。
$str = "http://www.opentip.com";
$reg = "/(http)\:\/\/(.*)\.(com)/s";
if(preg_match($reg,$str,$arr)){
echo "match the reg!"."\n";
echo "result:\n";
print_r($arr);
}else{
echo "no match!";
}
//match the reg!
//result:
//Array(
[0] => http://www.opentip.com //全模式
[1] => http //第一个子模式
[2] => www.opentip //第二个子模式
[3] => com //第三个子模式
)
第四个作用: 反向引用