关于正则表达式有以下几个说法,可以参考一下:
- 如果可以使用字符串处理函数完成的任务,就不要使用正则表达式。这是从处理效率上来讲的。
- 有一些复杂的操作,只能够使用正则表达式完成。
- 正则表达式可以在很多计算机语言中应用。
- 正则表达式也称为一种模式表达式、
- 正则表达式就是通过构建具有特定规则的模式,与输入的字符信息比较。再进行分割、匹配、查找、替换等工作。
- 如果正则表达式不和函数一起使用,则就是一个字符串,如果将正则表达式,放入到某个函数中使用,才能发挥出正则表达式的作用。
- 用到分割函数中 就可以用这个正则去分割字符串。用到替换函数中,就可以用这个正则去替换字符串。
- 学习正则表达式要学习两方面。
- 正则表达式的模式是如何编写的
- 学习正则表达式的强大处理函数
正则表达式查用术语
- 定界符
- 原子
- 元字符
- 脱字符
- 通配符(正向预查,反向预查)
- 反向引用
- 惰性匹配
- 注释
- 零字符宽度
定界符
定界符用来表示一个正则表达式的开始开始和结束(也不是正则的结束)举例来说:"/<img\s*src=\".*?\"\>/" "/<img\s*src=\".*?\"\>/u".其中用红色标记的就是定界符。通常使用"/"来做定界符,也可以用"#"来做定界符。使用"#"还是使用"/"依据个人喜好而定。一个建议是当要匹配的字符串中有很多的"/"字符的时候,就尽量用"#"可以减少代码。使用"#"就不必对"/"进行转义。
广义的来说,字母数字和正斜线以外的任何字符 都可以为定界符。
代码:
//$regex = '/^http:\/\/([\w.]+)\/([\w]+)\/([\w]+)\.html$/i';
$regex = '#^http://([\w.]+)/([\w]+)/([\w]+)\.html$#i';
$str = 'http://www.zmax99.com/test/test.html';
$matches = array();
if(preg_match($regex ,$str ,$matches))
{
print_r($matches);
}
分析一下上面的正则表达式:
##表示定界符
^表示只匹配用http:开头的字符串
[]表示匹配中括号中的任意一个字符
\w表示 匹配字 也就是a-z A-Z 0-9 _
+表示前面的字符必须要有一个,可以有多个。
$表示结尾
i表示忽略大小写 另外x表示忽略空格
()表示将这个作为项单独作为一个结果项返回。
综合上述,这个正则表达式要匹配的字符串是,以http:开头,以.html结尾,并且路径深度为2(“/”的个数)的字符串
Array
(
[0] => http://www.zmax99.com/test/test.html
[1] => www.zmax99.com
[2] => test
[3] => test
)
原子
原子是正则表达式的最基本的组成单位,而且必须至少要包含一个原子。只要一个正则表达式可以单独使用的字符,就是原子。
原子包含:所有打印和非打印字符。所有有意义的字符,想作为原子使用,统统使用”\“转义字符转义。
”\“ 转义字符可以将所有有意义的字符转义成没有意义,也可以将没有意义的字符转义成有意义的字符。
在正则表达式中可以使用一些代表范围的原子:
- \d : 表示任意一个十进制数字
- \D: 表示任意一个除数字之外的字符
- \s: 表示任意一个空格符 [\t\n\r]
- \S: 表示任意一个非空白
- \w: 表示a-z A-Z 0-9 _
- \W:匹配非字
- []:匹配方括号中的任何一个元字符。
- 匹配所有的奇数/[13579]/
- 在[]中使用 - 表示一段范围[1-7] 匹配1到7中任意一个
- [^]表示取反,[^1-7]表示匹配除了1-7之外任意一个原子。
元字符
元字符是一种特殊的字符,是用来修饰原子用的,不可单独出现。
- * :表示其前面的原子可以出现的次数是0次1次或者多次
- + :表示其前面的原子可以出现1次或者多次,最少一次!
- ?:表示其前面的原子可以出现0次或者1次…………
- . :默认情况下表示除了换行符外任意一个字符
- 如果.在[]中使用,就表示一个点,不代表其他意思
- $ :修饰整个字符串 表示以什么结尾。
^ : 修饰整个字符串 表示以什么开头
如果^在表达式的开头,那么就表示以某某字符开头。如果在[]中,那么就表示取反。
|:表示或关系。
/a|b/ 表示匹配a或者b 只要在字符串中a或者b出现一次就匹配成功
/cat|dog/ 表示匹配cat 或者dog 二者出现一个就可以了 (特别注意并不是匹配t 和 d)
{} :{m} 用于自己定义前面原子出现的次数
/zhang{4}/ 指定zhang在字符串中只能出现4次
{m,}用于指定前面的原子最少出现m次。
{m,n}要是要出现的次数大于m次 小于 n次
():
- 作为大原子使用。
- 作为子模式。
- 全部匹配放到数组的第一个元素中 ,每一个小括号是一个子模式,按顺序放到数组中。
- 改变优先级。
- 取消模式 ;在模式前面加上?:
- 反向引用。可以在模式中直接将子模式取出,再作为正则表达式的一部分。\1 取第一个子模式 \2取第二个子模式。
\b :用来匹配边界的。表示一个边界。
\B:表示一个非边界。
$pattern0="/is/"
$pattern1 = "/\bis\b"; 两边都有边界
$pathern2 ="/\Bis\b/" ;左边没有边界,右边有边界
$pathern3 ="/\bis\B/" ;左边有边界,右边没有边界
$pathern4 ="/\Bis\B/" ;两边都没有边界
所谓的边界就是空格或者其他的换行符,通俗一点就是不可打印的字符。
$string ="this is island!";
如果是$pattern0则匹配所有的is
如果是$pattern1则匹配中间的is 两边都有边界 $string ="this is island!";
如果是$pattern2则匹配左边的is 左边没有边界,右边有边界 $string ="this is island!";
如果是$pattern3则匹配右边的is 左边有边界,右边没有边界 $string ="this is island!";
如果是$pattern4则不匹配 两边都没有有边界 。
脱字符
"\"叫做逃脱字符。用于转义一些特殊的字符
通配符(lookarounds):断言某些字符串中某些字符的存在与否
lookarounds分为两种:
- lookaheads(正向预查?=)
- lookbehinds(反向预查?<=)
正向预查相对应的(?!)表示否定的意思。反向预查(?<=)相对于的(?<!)表示否定意思。
$regex = '/(?<=\d)d(?=[A-Z])/';//d 前面是一个数字,d后面是一个大写字符
$str='abc00dEfgk';
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
print_r($matches);
}
结果:
Array
(
[0] => Array
(
[0] => d
)
)
字符宽度:零
代码:
$regex = '/HE(?=L)LO/i';
$str = 'HELLO';
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
print_r($matches);
} echo "\n";
结果为无法匹配。
这是因为?=L它断定E后面是一个L字符,但是这个L字符不算子匹配字符串中(感觉有点拗口)。如果将$str换成$str=''HELO“就会匹配。
反向引用
在同一个表达式内的引用叫做反向引用。
代码:
$regex = '/^(zmax)[\s]+is[\s]+\1$/';
$str = 'zmax is zmax';
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
print_r($matches);
}
结果:
Array
(
[0] => Array
(
[0] => zmax is zmax
)
[1] => Array
(
[0] => zmax
)
)
在$regex中使用\1来引用前面第一个括号匹配的zmax
命名结果组(命名捕获组)
格式:(?=<组名>) 命名一个结果组
(?p=组名) 使用一个结果组的结果 和\1类似。只是在结果中不输出。
代码:
//$regex = '/^(zmax)[\s]+is[\s]+\1$/';
$regex = '/^(?Pzmax)[\s]+is[\s]+(?P=who)$/';
$str = 'zmax is zmax';
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
print_r($matches);
}
结果:
Array
(
[0] => Array
(
[0] => zmax is zmax
)
[who] => Array
(
[0] => zmax
)
[1] => Array
(
[0] => zmax
)
)
这样我们就可以使用一个更加有意义的名称来使用结果了。
惰性匹配
?:如果起那么有限定符,会使用最小的数据。如"*“会选取0个,”+“会选取一个,{3,6}会选取3个。
$str="hellllllllllllllllllll";
$pattern0 = '/hel*/'; 匹配 hellllllllllllllllllll(贪婪模式)
$pattern1 = '/hel*?/'; 匹配 he
$pattern2 = '/hel+?/'; 匹配 hel
$pattern3 = '/hel{3,6}?/';匹配 helll
正则表达式的注释
格式:(?# 注释的内容) 。在复杂的正在表达式中使用。增加程序的可读性。
代码:
$regex = '/
^host=(?<!\.)(?P[\d.]+)(?!\.) (?#主机地址)
\|
(?P[\w!@#$$^*()_+\-]+) (?#用户名)
\|
(?P[\w!@#$%^&*()_+-]+) (?#密码)
(?!\|)$
/ix';
$str="host=192.168.1.93|root|test";
$matches = array();
if(preg_match_all($regex ,$str ,$matches))
{
print_r($matches);
}
结果:
Array
(
[0] => Array
(
[0] => host=192.168.1.93|root|test
)
[host] => Array
(
[0] => 192.168.1.93
)
[1] => Array
(
[0] => 192.168.1.93
)
[username] => Array
(
[0] => root
)
[2] => Array
(
[0] => root
)
[password] => Array
(
[0] => test
)
[3] => Array
(
[0] => test
)
)
模型修正符
模式修正符的作用是对正则表达式进行调优
- 模式修正符就是几个字母
- 可以一次使用一个 ,每一个具有一定的意义
i :在和模式匹配的时候不区分大小写。
m: 默认情况 PHP将字符串视为1行。加上m修正符后 为多行。
s : 视为单行
. 默认不表示换行符 加上s后就可以表示换行。
x :忽略模式中的空格
e :在替换函数中使用
A:强制模式开头
Z:表示必须以模式结尾
U:取消贪婪模式。
当不支持模式修正符的时候 ,使用?可以解决贪婪模式造成的影响。
PHP中正则表达式配合使用的函数
1,字符串的匹配
preg_match : 第一个参数模式
第二个参数要查找的字符串
第三个参数存放匹配的模式的字符串。
但这个函数只匹配一次。并不会匹配所有的。preg_match_all 可以匹配所有的字符串。将匹配的结果放在第三个参数中。
2,在字符串中查找
str_replace: 第一个参数 要查找的字符串
第二个参数 要替换为的字符串
第三个参数需要替换的字符串
返回替换后的结果。PHP函数strstr()也有类似功能 。strstr函数第一个参数 将被执行查找的字符串。 第二个参数 搜索的内容字符串。返回查找到的字符串以及以后的所有内容。
echo strstr('this is a test good!','test');
输出 test good.
stristr()和上一个一样,只是不用区分大小写。