PHP-正则表达式
正则表达式
正则表达式被用来检索或替换那些符合某个模式的文本内容。 许多程序设计语言都支持利用正则表达式进行字符串操作。例如:JavaScript、PHP、ASP、JAVA、Perl、C#、.NET、ColdFusion、Python、Visual Basic、MYSQL、LINUX、VI编辑器等等语言都支持正则表达式。
简单来说正则表达式就是完成字符串的增、删、改、查。
定界符
正则表达式语句需要由分隔符(定界符)闭合包裹,分隔符可以使任意非字母数字, 非反斜线, 非空白字符
经常使用的分隔符是正斜线(/), hash符号(#) 以及取反符号(~)。
建议使用//做为定界符,因为与js一致。
$status = preg_match(‘/houdunren/‘, ‘houdunren.com‘); var_dump($status);
元字符
元字符是正则表达式中的最小元素,只代表单一(一个)字符。下面是元字符列表
元字符 | 说明 | 范围 |
---|---|---|
\d | 匹配任意一个数字 | [0-9] |
\D | 与除了数字以外的任何一个字符匹配 | [^0-9] |
\w | 与任意一个英文字母,数字或下划线匹配 | [a-zA-Z_0-9] |
\W | 除了字母,数字或下划线外与任何字符匹配 | [^a-zA-Z_0-9] |
\s | 与任意一个空白字符匹配 | [\n\f\r\t\v] |
\S | 与除了空白符外任意一个字符匹配 | [^\n\f\r\t\v] |
\n | 换行字符 | |
\t | 制表符 |
var_dump(preg_match(‘/\d/‘, ‘1‘)); var_dump(preg_match(‘/\D/‘, ‘h‘)); var_dump(preg_match(‘/\w/‘, ‘_‘)); var_dump(preg_match(‘/\W/‘, ‘@‘)); var_dump(preg_match(‘/\s/‘, ‘ ‘)); var_dump(preg_match(‘/\S/‘, ‘h‘)); var_dump(preg_match(‘/\n/‘, "\n")); var_dump(preg_match(‘/\n/‘, ‘ ‘)); var_dump(preg_match(‘/\t/‘, "\t"));
元字符表(原子表)
在一组字符中匹配某个元字符,在正则表达式中通过元字符表来完成,就是放到方括号中。
原子表 | 说明 |
---|---|
[] | 只匹配其中的一个原子 |
[^] | 只匹配"除了"其中字符的任意一个原子 |
[0-9] | 匹配0-9任何一个数字 |
[a-z] | 匹配小写a-z任何一个字母 |
[A-Z] | 匹配大写A-Z任何一个字母 |
. | 点在正则中表示除换行符外的任意字符 |
匹配聊了 678
外的任何字符
$status = preg_match(‘/[^678]/‘, 678); var_dump($status);
匹配大小写字母
$status = preg_match(‘/[a-zA-Z]/‘, ‘a‘); var_dump($status);
用.
匹配字符
$status = preg_match(‘/./‘, ‘houdunren‘); var_dump($status);
下面是通过原子表拆分字符串
$str ="@3.jpg#4.jpg"; $arr = preg_split(‘/[@#]/‘,$str); //按正则表达式拆分字符串 print_r($arr); //输出结果 Array ( [0] => 1.jpg [1] => 2.jpg [2] => 3.jpg [3] => 4.jpg )
原子组
- 如果一次要匹配多个元子,可以通过元子组完成
- 原子组与原子表的差别在于原子组一次匹配多个元子,而原子表则是匹配成功表中的一个元字符就可以
- 元字符组用()表示
下面是使用正则表达式将houdunwang
字符中的 houdun
描红。
$str = "官网www.houdunwang.com 论坛http://bbs.houdunwang.com,我在网名叫houdun"; $preg = "/(houdun)wang/is"; $newStr= preg_replace($preg, ‘<span style="color:#f00">\1</span>wang‘, $str); echo $newStr;
匹配字符边界
如果想匹配字符的边界,边界包括空格、标点符号、换行等,可以使用正则表达式的匹配字符边界修饰符如下。
符号 | 说明 |
---|---|
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束,忽略换行符 |
$status = preg_match(‘/^houdunren$/‘, ‘houdunren‘); var_dump($status); //返回真
选择修释符
| 这个符号带表选择修释符,也就是 | 左右两侧有一个匹配到就可以。
下面是通过选择修释符将域名修改为 houdunren
$str = "http://www.baidu.com与新浪网http://www.sina.com"; $preg = "/\.(baidu|sina)\./is"; echo preg_replace($preg, ‘.houdunren.‘, $str);
匹配域名后缀
$str = ‘来了,老弟!有问题就上 houdunren.com 或 houdunwang.com 我们在那里等你‘; $preg = ‘/(houdunren|houdunwang)\.com/‘; $replace = ‘<a href="http://www.\1.com">\1.com</a>‘; echo preg_replace($preg, $replace, $str);
重复匹配
如果要重复匹配一些内容时我们要使用重复匹配修饰符,包括以下几种。
因为正则最小单位是元字符,而我们很少只匹配一个元字符如a、b所以基本上重复匹配在每条正则语句中都是必用到的内容
符号 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
var_dump(preg_match(‘/^.*$/‘, ‘‘)); //* 零个及空字符串也是可以的 var_dump(preg_match(‘/^[0-9]+$/‘, ‘1976‘)); // 返回真 var_dump(preg_match(‘/^9?$/‘, ‘99‘)); // 返回假 var_dump(preg_match(‘/^9{2}$/‘, ‘99‘)); // 返回真 var_dump(preg_match(‘/^[0-9]{2,}$/‘, ‘123‘)); //返回真 var_dump(preg_match(‘/^[0-9]{2,3}$/‘, ‘1234‘)); // 返回假,只能2~3位
下面匹配域名操作
$web = ‘sina.com‘; var_dump(preg_match(‘/^[a-z-0-9-]+\.(com|net|com\.cn|org|cn)$/‘, $web));
下面是把 h1
标签内容加上超链接
$str = <<<html <h1>hello houdunren</h1> html; echo preg_replace(‘/<h1>(.+)<\/h1>/‘, ‘<a href="http://www.houdunren.com">\1</a>‘, $str);
禁止重复匹配
正则表达式在进行重复匹配时,默认是贪婪匹配模式,也就是说会尽量匹配更多内容,但是有的时候我们并不希望他匹配更多内容,这时可以通过?进行修饰来禁止重复匹配。
符号 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
$str = ‘123456‘; preg_match(‘/\d+?/‘,$str,$matches); print_r($matches);
因为增加了 ?
所以只匹配数字1
下面是使用禁止贪婪符替换将h1标签内容倾斜处理
$str = "<h1>你好</h1><h1>向军大叔</h1>"; $preg = ‘/<h1>(.*?)<\/h1>/‘; $replace = ‘<h1><em>\1</em></h1>‘; echo preg_replace($preg,$replace,$str);
下面是替换h1-h6标签内容,就不需要使用禁止贪婪符了
$str = "<h1>你好</h1><h2>向军大叔</h2>"; $preg = ‘/<h([1-6])>(.*)<\/h\1>/‘; $replace = ‘<h\1><em>\2</em></h\1>‘; echo preg_replace($preg,$replace,$str);
模式修正符
正则表达式在执行时会按他们的默认执行方式进行,但有时候默认的处理方式总不能满足我们的需求,所以可以使用模式修正符更改默认方式。
符号 | 说明 |
---|---|
i | 不区分大小写字母的匹配 |
s | 将字符串视为单行,换行符做普通字符看待,使“.” 匹 配任何字符 |
x | 忽略空白及#符号,根据此特性可以添加正则注释 |
m | ^与$符匹配按行匹配 |
A | 强制从字符串开始匹配(多行时默认以每行开始设置) |
D | 以$结尾时不允许后面有换行(使用\m时无效) |
\i修正符不匹分大小示例
$str = ‘https://www.HoudunREN.com 后盾人‘; $preg = ‘/https:\/\/www.houdunren.com/i‘; $replace= ‘<a href="\0">\0</a>‘; echo preg_replace($preg,$replace,$str);
\s 将字符串示为单行操作
$preg = ‘#(<h1>)(.*?)(</h1>)#s‘; preg_match_all($preg,$str,$matches); //print_r($matches); $replace = ‘\1<span style="color:red">\2\3‘; echo preg_replace($preg,$replace,$str);
\m
使用 ^ 与 $ 按单行操作文本
$str = <<<php #1 2022-02-12 后盾人 @#100 雅虎网 #2 2033-09-11 向军大叔 php; $preg = ‘/^#\d+.*[\r|\n]$/m‘; preg_match_all($preg, $str, $matches); print_r($matches);
\x字符忽略空白和添加正则注释
添加注释
$str=‘houdunren.com‘; $preg = ‘/^h # 这是匹配以 h 开始的内容 /x‘; echo preg_replace($preg,‘‘,$str);
当设置了\x后
#
会被忽略,如果正则中使用#需要转义处理$str=<<<php #1 后盾人#1 #2 向军大叔#2 php; $preg = ‘/^ \#\d #匹配以数字开始 +.* $ #后跟任何字符 /mx‘; echo preg_replace($preg,‘‘,$str);
\U 与?功能相似意为禁止贪婪匹配
$str = <<<php <h1>后盾人</h1> <h1>向军大叔</h1> php; ; $preg = ‘#<h1>.*</h1>#sU‘; preg_match_all($preg,$str,$matches); print_r($mat ches);
\A 与 ^限定符使用效果相似,必须以目标字符串开始。下面是验证邮箱例子
$str = ‘‘; $preg = ‘/\[\w\.]+/A‘; preg_match_all($preg,$str,$matches); print_r($matches);
\D 修正符使用不允许以换行结束
$str = <<<php 3a\n php; $preg = ‘/\d+a$/D‘; preg_match_all($preg,$str,$matches); print_r($matches);
常用函数
preg_match
获取第一个匹配的内容
$str= ‘@3‘; preg_match(‘/\d+/‘,$str,$matches); print_r($matches);
preg_match_all
获取所有匹配的内容
$str= ‘@3‘; preg_match(‘/\d+/‘,$str,$matches); print_r($matches);
preg_split
通过正则表达式拆分字符串
$str= ‘#3‘; $arr = preg_split(‘/@|#/‘,$str); print_r($arr);
preg_replace
通过正则表达式替换
$str= ‘#3‘; echo preg_replace(‘/@|#/‘,‘-‘,$str);
preg_replace_callback
使用回调函数进行替换操作
$str = ‘@3‘; echo preg_replace_callback(‘/\d+/‘,function ($matches) { return $matches[0]+100; }, $str);