07_RegExp

基础

定义

正则表达式是具有特殊语法结构的字符串
Regular Expression reg regexp

作用

  1. 表单验证
  2. 网络爬虫

函数库

  1. PCRE函数库

Perl兼容的正则表达式函数库

  1. POSIX(不推荐使用)

特点

  1. 语法结构复杂
  2. 执行效率低

相对于同功能的字符串函数而言

  1. 功能强大

语法

语法结构

/正则表达式/模式修饰符

定界符

  1. 正则表达式必须写在定界符里面
  2. 除了数字,字母和反斜杠的任意字符都可以做为定界符,一般用//
  3. 定界符必须成对出现
  4. $pattern模式规则的意思
$pattern="//";//定界符
$pattern="##";//有效
$pattern="11";//无效 定界符不能是数字
$pattern="AA";//无效 定界符不能是字母
$pattern="\\";//无效 定界符不能是反斜杠
$pattern="/#";//无效 定界符必须成对出现

原子

  1. 正则表达式中的最小原子
  2. 一个正则表达式若想有意义,则至少包含一个原子
  3. 普通字符 a1-

元字符(特殊的原子)

  1. \s 匹配空格 space
  2. \S 匹配非空格
  3. \d 匹配数字 decimal
  4. \D 匹配非数字 [^0-9]
  5. \w 匹配单词(数字,大小写,下划线)[0-9a-zA-Z_]
  6. \W 匹配非单词 [^0-9a-zA-Z]
  7. . 匹配任意字符
$subject="Hello,  World";
$pattern='/\s/';//\s匹配空格\
//返回匹配结果的次数
//将返回结果赋值给第三个参数$matches

echo preg_match_all($pattern,$subject,$matches);

echo "<pre>";
print_r($matches);
echo "</pre>";

$pattern="/\S/";//\S大s 匹配非空格
echo preg_match_all($pattern,$subject,$matches);

echo "<pre>";
print_r($matches);
echo "</pre>";
$subject="This it test";
$pattern="#s#";//普通的原子
preg_match_all($pattern,$subject,$matches);

echo "<pre>";
print_r($matches);
echo "</pre>";
$subject= "I am 18";
$pattern="/\d/";//匹配数字

preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

$pattern="/\D/";//匹配数字

preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
function isNumber($value){
    //思路:如果非数字匹配不到,则为纯数字
    //\D匹配失败时,匹配对象为纯数字
    $pattern="/\D/";
    if (!preg_match_all($pattern,$value)){
        return true;
    }
    return false;
}
$value='123adb';
$value='123';
$suc=isNumber($value);
echo $suc?"是数字":"不是数字";
$subject="I am_ 18.";
$pattern="/\w/";

preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

$pattern="/\W/";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

$subject="I am 18.";
$pattern="/./";

preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

$pattern="/\./";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

转义符(escape)

  1. \n 换行符newline
  2. \t 制表符
  3. 声明 双引号可以解析以上的的转义符,单引号不行

字符组

正字符组
  1. 可以在正字符组中给出多个原子,多个原子是"或"的关系
$pattern="/[is]/";//匹配字母i或者字母s
  1. 常用的字符组(匹配范围)[0-9]相当于\d
  2. [a-z]
  3. [A-Z]
负字符组
  1. [^xxxxxx]

量词

  1. 用来修饰正则表达式出现的次数(数量)
  2. 语法{n}精确匹配==n==位
  3. {n,}开区间匹配
  4. {n,m}闭区间匹配,其中n,m都为正整数,n<m
$subject="This iis test";
$pattern="/i{2}/";
//匹配多位(,后面没有空格)
$pattern="/i{1,}/";
$pattern="/i{2,3}/";//匹配2位到3位
  1. ? 匹配01{0,1}
  2. * 匹配0位或多位{0,}
  3. + 匹配1位或多位{1,}
$pattern="/s\s?/";//匹配"s"或"s空格" ?代表0或1位
$pattern="/s\s*/";//*匹配0到多位
$pattern="/s\s+/";//+匹配1到多位
//匹配手机号
//17375821270
//手机号是11位的数字 \d{11}
//手机号的第一位数字为1 1\d{10}
//13X 15X 17X 18X
//手机号第二位可能的数字是3578  [3578]
//手机号第三位也有号段(暂不考虑)
//177-1234-1234  1[3578]\d-?\d{4}-?\d{4}
//17712341234
//0177-1234-1234 0?1[3578]\d-?\d{4}-?\d{4}
//+86 0177-1234-1234 (暂时省略)
//匹配开头和结尾(边界),使用定位点符号 ^ $  ^0?1[3578]\d-?\d{4}-?\d{4}$
//     /^正则表达式$/
//思路:
//1.首先分析目标字符串的规律(模式)
//2.将规律(模式)翻译成正则表达式
//3.验证
function isMobile($mobile){
    $pattern="/^0?1[3578]\d-?\d{4}-?\d{4}$/";
    if(preg_match($pattern,$mobile)){
        return true;
    }
    return false;
}
$mobile="0173-7582-1270";
$suc=isMobile($mobile);
echo $suc?$mobile."手机号合法":$mobile."手机号非法";
//数字规律
//邮政编码
//身份证号
//区号
//QQ号
//....

定位点

  1. ==^== 匹配开头\A
  2. $ 匹配结尾\Z
  3. \b匹配边界
  4. \B匹配非边界
//定位点
//^匹配开头
//$匹配结尾
$subject="This is test";
$pattern='/^T/';//匹配左侧边界
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/t$/";//匹配右侧边界
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/s\b/";//匹配右侧为边界的小写字母s
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
$pattern="/\Bs\B/";//匹配非边界小写字母s
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

选择路径

  1. | 或,a|b
$subject="This is test";
$pattern="/is|t/";//匹配is或者t
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";

模式修饰符

  1. i "//i"忽略大小写
$subject="This is test";
$pattern="/t/i";//忽略大小写,匹配字母t
//应用场景:对大小写不敏感时,使用模式修饰符i
//例如:<table>或者<TABLE> 都是有效的HTML标签
  1. U ungreedy 非贪婪模式(懒惰模式)
    1. PHP正则默认是贪婪模式
    2. 贪婪:在满足条件的前提下尽可能多的匹配
    3. 可以混合使用 Ui
    4. ==.*== 贪婪模式
    5. ==.*?== 非贪婪模式(量词加问号限定死)
//贪婪模式
$subject="<td>zhangsan</td><td>lisi</td>";
$pattern="/<td>.+<\/td>/";//\转义 不然和定界符冲突
/*
* <pre>Array
(
   [0] => Array
       (
           [0] => <td>zhangsan</td><td>lisi</td>
       )

)
</pre>*/ //贪婪模式 因为 <td>zhangsan</td><td>lisi</td> zhangsan</td><td>lisi 也满足条件下尽可能多的匹配
//非贪婪模式
$pattern="/<td>.+<\/td>/U";
preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
/*
*
* Array
(
   [0] => Array
       (
           [0] => zhangsan
           [1] => lisi
       )

)
*/ //非贪婪模式

捕获组

  1. (XXXX)描述正则表达式中的子表达式
    1. 编号为0 的结果,匹配整个正则表达式
    2. 然后从1开始,按照小括号的顺序从左向右依次排序
  2. 引用
    1. 正向引用
      1. 在代码中(正则表达式之外)使用匹配成为正向引用
    2. 反向引用
      1. 语法\number number匹配结果对应的索引值
      2. 反向引用使用的是匹配结果,而不是正则表达式本身

// 03_group.php
// 捕获组  ()

// 假定该日期是一个生日
$subject = "2017-12-07";
// 日期格式分析:
// 年:    1900-现在  (19|20)\d{2}    \d{4}
//        19\d{2}|200\d|201[0-7]
// 月:    01 02 .... 09 10 11 12
//       十位数: 0?[1-9]|1[0-2]
//
// 日:   01 ... 09
//       10 ... 19
//       20 ... 29
//       30 31
//       0?[1-9]|1[0-9]|2[0-9]|3[01]
//       0?[1-9]|[12][0-9]|3[01]
//       0?[1-9]|[12]\d|3[01]

// $pattern = "/(YYYY)-(MM)-(DD)/";
// $pattern = "/(YYYY)-((MM)-(DD))/";
$pattern = "/(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])/";

preg_match_all($pattern,$subject,$matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
  1. (?:xxxx)非捕获组

匹配函数

  1. preg_match_all($pattern,$subject,$matches);

返回匹配的次数,二维数组

  1. preg_match($pattern,$subject);

返回匹配的结果,一维数组

查找替换

preg_replace($pattern,$replacement,$matches)str_replace($search,$replacement,$matches)

$subject="This is test";
//将字符串中的空格替换成下划线
echo str_replace(" ","_",$subject)."<hr>";
$pattern="/\s/";
echo preg_replace($pattern,"_",$subject)."<hr>";
//声明:
//如果普通字符串函数与正则表达式函数能够完成同样的功能;
//则优先使用普通字符串函数(正则效率低)
$subject="This2 i4s te6st";
//将字符串中的数字替换成下划线
$pattern="/\d/";//匹配数字
echo preg_replace($pattern,"_",$subject)."<hr>";
//将html标签去掉
//<p>hello</p>

正则分割

array pre_split($pattern,$subject)array explode($delimiter,$string)

$subject="This is test";
$arr1=explode(" ",$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";

$pattern="/\s/";
$arr1=preg_split($pattern,$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
//声明:
//如果普通字符串函数与正则表达式函数能够完成同样的功能;
//则优先使用普通字符串函数(正则效率低)

//根据右侧边界字母s进行分割
$pattern="/s\b/";
$arr1=preg_split($pattern,$subject);
echo "<pre>";
print_r($arr1);
echo "</pre>";
//普通函数达不到要求,必须要正则来写了

返回匹配模式的数组条码

preg_grep($pattern,$input);

//匹配数组元素
//grep =Global Regular ExPression
// 全局正则表达式
$pattern="/te/";
$input=array("time","term","team");
$arr=preg_grep($pattern,$input);

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

推荐阅读更多精彩内容