PHP正则表达式

强颜欢笑 提交于 2019-11-27 10:00:35

PHP正则表达式

说明:根据《PHP核心技术与最佳实践》做的一点笔记。

如有错误或建议,请指教。


 一、PHP有两套正则函数:

(1)由PCRE库提供的函数,以前缀“preg_”命名,PCRE意思是兼容Perl的正则表达式的缩写首字母。
(2)由POSIX扩展提供的函数,以前缀“ereg_”命名,POSIX意思是UNIX可移植操作系统接口的首字母。

  注意:自PHP5.3以后,不再推荐使用POSIX正则函数库,会报Deprecated级别的错误。


 二、正则表达式的组成:

  一个正则表达式分为三个部分:分隔符、表达式、修饰符。


 三、测试工具:

(1)RegexTester。
(2)Firefox的扩展Regular Expression Tester。


四、常用的pcre函数:

常用函数一:preg_match()和preg_match_all():

(1)preg_match($pattern,$str,[$matches])
preg_match()返回 pattern 的匹配次数。 
它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索


(2)preg_match_all($pattern,$str,[$matches])。
返回完整匹配次数(可能是0),或者如果发生错误返回FALSE

示例:

$res = preg_match_all('/(foo)(bar)(baz)/', 'foobarbaz', $matches);var_dump($res);//结果:int 1
var_dump($matches);

打印结果:

array (size=4)
    0 => 
        array (size=1)
            0 => string 'foobarbaz' (length=9)
    1 => 
        array (size=1)
            0 => string 'foo' (length=3)
    2 => 
        array (size=1)
            0 => string 'bar' (length=3)
    3 => 
        array (size=1)
            0 => string 'baz' (length=3)    

 

常用函数二:preg_filter和preg_replace

功能:执行一个正则表达式搜索并替换。
preg_filter只返回匹配到的替换后的结果。
preg_replace返回完整的替换后的字符串。

参数顺序(每个参数可以是字符串,也可以是数组):
preg_filter($pattern, $replace, $str)
preg_replace($pattern, $replace, $str)

示例:
1、当$str是字符串时,两个函数效果一样。
$str = '2019年08月14日';
$pattern = array('/年/','/月/','/日/');
$replace = array('-','-','');

$a = preg_filter($pattern, $replace, $str);
var_dump($a);//结果:2019-08-14

$a = preg_replace($pattern, $replace, $str);
var_dump($a);//结果:2019-08-14

2、当$str是数组时,两个函数效果不一样。
$str = array('2019年08月14日','2018-01-06','闰年','一年');
$pattern = array('/年/','/月/','/日/');
$replace = array('-','-','');

$a = preg_filter($pattern, $replace, $str);
var_dump($a);

$a = preg_replace($pattern, $replace, $str);
var_dump($a);

结果分别是:
array (size=3)
0 => string '2019-08-14' (length=10)
2 => string '闰-' (length=4)
3 => string '一-' (length=4)

array (size=4)
0 => string '2019-08-14' (length=10)
1 => string '2018-01-06' (length=10)
2 => string '闰-' (length=4)
3 => string '一-' (length=4)


preg_replace_callback()执行一个正则表达式搜索并且使用一个回调进行替换.
示例:
$str = '2019年08月14日';
$pattern = array('/年/','/月/','/日/');
$res = preg_replace_callback($pattern, function($matches){
return '-';
}, $str);
var_dump($res);
结果:string '2019-08-14-'


常用函数三:preg_last_error

功能:返回最后一个PCRE正则执行产生的错误代码
示例:
preg_match('/(?:\D+|<\d+>)*[!?]/', 'foobar foobar foobar');
if (preg_last_error()) {
  print preg_last_error();
}

常用函数四:preg_grep($pattern,$arr,$flags)

功能:返回给定数组中与模式pattern 匹配的元素组成的数组.
若flags设置为PREG_GREP_INVERT时,返回不匹配的元素组成的数组。
示例:
$arr = array('php','html','js','java','jquery','python');
$pattern = '/p/';

$res = preg_grep($pattern,$arr);
var_dump($res);

$res = preg_grep($pattern,$arr,PREG_GREP_INVERT);
var_dump($res);

array (size=2)
0 => string 'php' (length=3)
5 => string 'python' (length=6)

array (size=4)
1 => string 'html' (length=4)
2 => string 'js' (length=2)
3 => string 'java' (length=4)
4 => string 'jquery' (length=6)


常用函数五:preg_split()

功能:通过一个正则表达式分隔字符串.
返回数组,失败返回false。
示例:
以字符串中的空格和,分割字符串成数组
$str = 'php , html , js , javascript';
$keywords = preg_split("/[\s,]+/",$str);
var_dump($keywords);
结果:
array (size=4)
0 => string 'php' (length=3)
1 => string 'html' (length=4)
2 => string 'js' (length=2)
3 => string 'javascript' (length=10)


五、正则表达式中的元字符:

. 匹配除换行以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意空白字符
\d 匹配数字
\b 匹配单词开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
- 表示范围
[] 匹配括号中的任意一个字符
*、+、?量词


六、转义:

如果要想查找元字符本身,就需要使用转义\。
例如:\\、\.、\*等。

使用\Q和\E包围的元字符也被忽略,
例如:
\Q.*\E 就是匹配.*,不是任意字符。


七、反义:

匹配相反时,可以用反义。
\W 匹配任意不是字母、数字、下划线、汉字的字符。
\S 匹配任意不是空白字符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字符以外的字符


八、分支:

“|”表示分支。
示例:
[a|bc]d 表示匹配ad或bcd

当都是单字符时:[a|b|c] 等同于[abc]


九、分组:

使用小括号()进行分组.
示例:
匹配IP地址 (\d{1,3}\.){3}\d{1,3}


十、常用模式:

i 表示忽略大小写。 
m 多行匹配,仅当字符串中有换行符\n时才起作用。
. 作用是使表达式里的元字符.匹配换行符
U 懒惰模式
u 字符串被当成utf-8


 十一、环视:

(1)顺序肯定环视,语法(?=exp),意思是匹配以exp结尾的前面的部分。
示例:匹配以ing结尾的单词的前面部分
/\d\w+(?=ing\b)/

(2)逆序肯定环视,语法(?<=exp),意思是匹配exp后面的部分
示例:匹配以re开头的单词的后面部分
/(?<=re\b)\w+\b/

注意:环视不会占用字符,也就是说,环视它就是看一下是不是,但并不会匹配它,也就不会占用这个字符。

环视可以用来匹配html闭合标签里的内容,例如<div></div><h1></h1>等比较方便。

示例:

需求:匹配html的标题title中的内容:
$str = file_get_contents('http://localhost/index.html');
$pattern = '/(?<=<title>).*(?=<\/title>)/';
$res = preg_match_all($pattern,$str,$matches);
var_dump($res);//结果:int 1
var_dump($matches);
//结果:
array (size=1)
0 => 
array (size=1)
0 => string 'test' (length=4)


十二、运算符优先级:

转义符 > 括号和中括号 > 限定符


十三、关于分隔符:

正则表达式的分隔符只要遵循规则,是可以随意使用的。
例如:
$pattern = '/php/';
$pattern = '#php#';
$pattern = '~php~';
$pattern = '%php%';
这些都是可以的


 十四、附加:

(1)\b示例:

\ba\w*\b 匹配以a开头的单词(注意是单词,不是字符串,^才是以什么开头的字符串)。

$str = 'hello php,hello js';
$pattern = '/\bhello\b/';
$replace = 'nihao';
$a = preg_filter($pattern, $replace,$str);
var_dump($a);

结果:string 'nihao php,nihao js'

结论:被\b包围起来的表示是单独一个单词。
\babc\b 表示字符串中的abc是单词,
'abc'、'hello abc' 是正确的,
'abcd'、'helloabc'都是不正确的。

(2)等同写法:

[0-9]和\d一样,表示一位数字。
如果只考虑英文的话,[a-zA-Z_]和\w相同。

(3)关于^的使用:

当用作表示只能以字符开头时,只能用在正则表达式的最前端。
当用作取反时,只能用在字符组中,即中括号里。

(4)贪婪和懒惰匹配模式:

贪婪就是尽可能多地匹配字符。
懒惰就是尽可能少地匹配字符。

(5)可能发生的错误:

preg_match_all(): Unknown modifier 't'
分析错误原因:这种情况多数是由定界符的问题引起的.
解决方法:找到需要转义的特殊字符,加\转义一下。

(6)分组[^]的使用示例:

$str = 'abv vvv bac';
$pattern = '/[^ab]/';
$res = preg_match_all($pattern,$str,$matches);
var_dump($res);//结果:int 7
var_dump($matches);

结果:

array (size=1)
  0 => 
    array (size=7)
            0 => string 'v' (length=1)
            1 => string ' ' (length=1)
            2 => string 'v' (length=1)
            3 => string 'v' (length=1)
            4 => string 'v' (length=1)
            5 => string ' ' (length=1)
            6 => string 'c' (length=1)

说明:使用[]分组时,如果使用^非指定字符匹配时,整个分组里的都是不要匹配的。

即:/[^ab]/ 表示不匹配a,也不匹配b。

(7)示例,匹配html网页里的所有图片:

$str = file_get_contents('http://localhost/index.html');
$pattern = '/<img[^>]*?src=[\'|"]([^\'">]*?)[\'"][^>]*?>/';
$res = preg_match_all($pattern,$str,$matches);
var_dump($res);//结果:int 2
var_dump($matches);

结果:

array (size=2)
    0 => 
        array (size=2)
            0 => string '<img width="180" height="100" src='http://localhost/img/1.png' >'
            1 => string '<img width="180" src='http://localhost/img/2.png' height="100">'
    1 => 
        array (size=2)
            0 => string 'http://localhost/img/1.png'
            1 => string 'http://localhost/img/2.png'

(8)示例:匹配div的内容:

$str = '<div class="content">hello</div>';
$pattern = '#<div[^>]*?>([^<]*)<\/div>#';
$res = preg_match_all($pattern,$str,$matches);
var_dump($res);//1
var_dump($matches);

结果:

array (size=2)
  0 => 
    array (size=1)
      0 => string '<div class="content">hello</div>' (length=32)
  1 => 
    array (size=1)
      0 => string 'hello' (length=5)

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!