PHP七天系列之正则表达式

正则表达式


正则表达式被用来检索或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。例如:JavaScript、PHP、ASP、JAVA、Perl、C#、.NET、ColdFusion、Python、Visual Basic、MYSQL、LINUX、VI编辑器等等语言都支持正则表达式。

简单来说正则表达式就是完成字符串的增、删、改、查。

定界符


正则表达式语句需要由分隔符(定界符)闭合包裹,分隔符可以使任意非字母数字, 非反斜线, 非空白字符

经常使用的分隔符是正斜线(/), hash符号(#) 以及取反符号(~)。

建议使用//做为定界符,因为与js一致。

$status =  preg_match('/pfinalClub/', 'pfinalClub.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('/./', 'pfinalClub');
var_dump($status);

下面是通过原子表拆分字符串

$str ="1.jpg@2.jpg@3.jpg#4.jpg";
$arr = preg_split('/[@#]/',$str); //按正则表达式拆分字符串
print_r($arr); //输出结果 Array ( [0] => 1.jpg [1] => 2.jpg [2] => 3.jpg [

原子组


  • 如果一次要匹配多个元子,可以通过元子组完成

  • 原子组与原子表的差别在于原子组一次匹配多个元子,而原子表则是匹配成功表中的一个元字符就可以

  • 元字符组用()表示

下面是使用正则表达式将pfinalclub字符中的pfinal描红。

$str = "官网www.pfinalclub.com 论坛http://bbs.pfinal.com,我在网名叫pfinal";
$preg = "/(pfinal)club/is";
$newStr= preg_replace($preg, '<span style="color:#f00">\1club</span>', $str);
echo $newStr;

匹配字符边界


如果想匹配字符的边界,边界包括空格、标点符号、换行等,可以使用正则表达式的匹配字符边界修饰符如下。

符号 说明
^ 匹配字符串的开始
$ 匹配字符串的结束,忽略换行符
$status = preg_match('/^pfinalClub$/', 'pfinalClub');
var_dump($status); //返回真

选择修释符

| 这个符号带表选择修释符,也就是 | 左右两侧有一个匹配到就可以。
下面是通过选择修释符将域名修改为 pfinalClub

$str = "http://www.baidu.com与新浪网http://www.sina.com";
$preg = "/\.(baidu|sina)\./is";
echo preg_replace($preg, '.pfinalClub.', $str);

匹配域名后缀

$str = '来了,老弟!有问题就在 pfinalClub.com 或 pfinal.com';
$preg = '/(pfinalClub|pfinal)\.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 = 'baidu.com';
var_dump(preg_match('/^[a-z-0-9-]+\.(com|net|com\.cn|org|cn)$/', $web));

下面是把 h1标签内容加上超链接

$str = <<<html
<h1>hello pfinalClub</h1>
html;
echo preg_replace('/<h1>(.+)<\/h1>/', '<a href="http://www.pfinalClub.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>PF南丞</h1>";
$preg = '/<h1>(.*?)<\/h1>/';
$replace = '<h1><em>\1</em></h1>';
echo preg_replace($preg,$replace,$str);

下面是替换h1-h6标签内容,就不需要使用禁止贪婪符了

$str = "<h1>你好</h1><h2>PF南丞</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.pfinalClub.com PF南丞';
$preg = '/https:\/\/www.pfinalClub.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
PF南丞
@#100
雅虎网
#2 2033-09-11
PFinal
php;
$preg = '/^#\d+.*[\r|\n]$/m';
preg_match_all($preg, $str, $matches);
print_r($matches);

\x字符忽略空白和添加正则注释
添加注释

$str='pfinalClub.com';
$preg = '/^h
   # 这是匹配以 h 开始的内容
/x';
echo preg_replace($preg,'',$str);

当设置了\x后# 会被忽略,如果正则中使用#需要转义处理

$str=<<<php
#1
PF南丞#1
#2
PFinal#2
php;
$preg = '/^
\#\d  #匹配以数字开始
+.* $ #后跟任何字符
/mx';
echo preg_replace($preg,'',$str);

\U 与?功能相似意为禁止贪婪匹配

$str = <<<php
<h1>PF南丞</h1>
<h1>PF南丞小哥</h1>
php;
$preg = '#<h1>.*</h1>#sU';
preg_match_all($preg,$str,$matches);
print_r($matches);

\A 与 ^限定符使用效果相似,必须以目标字符串开始。下面是验证邮箱例子

$str = 'lampxiezi@qq.com';
$preg = '/\w+@[\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= '1@2@3';
preg_match('/\d+/',$str,$matches);
print_r($matches);

preg_match_all

获取所有匹配的内容

$str= '1@2@3';
preg_match('/\d+/',$str,$matches);
print_r($matches);

preg_split

通过正则表达式拆分字符串

$str= '1@2#3';
$arr = preg_split('/@|#/',$str);
print_r($arr);

preg_replace

通过正则表达式替换

$str= '1@2#3';
echo preg_replace('/@|#/','-',$str);

preg_replace_callback

使用回调函数进行替换操作

$str = '1@2@3';
echo preg_replace_callback('/\d+/',function ($matches) {
return $matches[0]+100;
}, $str);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 正则表达式介绍 正则表达式简介 正则表达式是用于描述字符排列和匹配模式的一种语法规则。它主要用于字符串的模式分割、...
    dptms阅读 10,905评论 1 9
  • 概述 正则表达式是一种描述字符串结果的语法规则,是一个特定的格式化模式,可以匹配、替换、截取匹配的字符串。常用的语...
    醉于麦田阅读 491评论 0 0
  • 正则表达式 php 正则表达式学习笔记 什么是正则表达式 正则表达式(Regular Expressions(Pe...
    Muxi_k阅读 324评论 0 0
  • 本文译自 制作正则引擎的作者 Jan Goyvaerts 为工具 RegexBuddy 写的教程版权归原作者所有注...
    极客圈阅读 3,259评论 0 25
  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 2,134评论 0 9