• 浅谈正则表达式-PHP为例


    第一次比较系统的学习正则表达式,本篇文章以PHP语言为例来学习。

    基本概念

      正则表达式=普通字符(如a-z)+分隔符(正斜线(/)、hash符号(#) 以及取反符号(~))+特殊字符(称为元字符) 两者的组合;

          PHP的正则有两种:POSIX和PERL(PCRE Perl Compatible Regular Expression),后者PHP支持得更好

    匹配原理

      简单描述下,通常是由字符串位置0开始尝试匹配,若匹配成功存储这个子串;若在某一个位置匹配失败则后移一个位置,从位置1开始重新匹配。直到匹配成功或者匹配到最后一个位置都没有找到成功的子串。

    匹配模式

      看名字,是不是想到了设计模式中的单例模式了呢?

    1. 贪婪模式

        在可匹配与可不匹配的时候,优先匹配,比如量词用*或+

      2. 懒惰模式

        在可匹配与可不匹配的时候,优先不匹配,比如量词用?。  *? 在正则中代表非贪婪匹配模式,会尽量少的匹配字符,如果不加 ?就是贪婪模式,此时通配符会把所有字符都匹配掉

    用途

    1. 查找:检查一个串是否包含某个子串,而子串是符合正则表达式条件的子串,最后得到所有符合条件的子串集合
    2. 替换:将上一条查找出来的子串替换成特定的字符串

    正则分隔符

    字符 说明 备注
    /表达式/ 一个完整的正则表达式的边界  若表达式内有/,需要用转义字符转义    $p="/ab//"
    #表达式# 一个完整的正则表达式的边界2  若表达式内有#,需要用转义字符转义    $p="#ab/##"
    ~表达式~ 一个完整的正则表达式的边界3  若表达式内有~,需要用转义字符转义    $p="~ab/#~~"
    |表达式| 一个完整的正则表达式的边界4 若表达式内有|,需要用转义字符转义    $p="|ab/#~||"

     

    元字符

    边界定位符

    字符 说明 备注
    ^开头,  用于子字符串的末尾,,表示子字符串必须出现在字符串的开头 见代码示例1
    $结尾 用于子字符串的末尾,,表示子字符串必须出现在字符串的末尾,可以和^搭配使用  
     匹配一个单词边界,匹配单词和空格之间的位置  
    B 匹配一个非单词边界,匹配单词和空格之间的位置  

    量词元字符

    字符 说明(都是返回能得到的最长子串) 备注
    * 0次或多次匹配前面的子表达式, 等价于{0,}
    0次或1次匹配前面的子表达式 等价于{0,1}懒惰模式就用这个
    + 1次或多次匹配前面的子表达式 等价于{1,}
    {n} n次匹配前面的子表达式  
    {n,} 大于等于n次匹配前面的子表达式  
    {,n} 小于等于n次匹配前面的自表达式  
    {n,m} 最少n次,最大m次,匹配前面的自表达式  

    普通元字符

      字符   说明 备注
     d  数字,等价于[0-9]  digit
     D  非数字,等价于[^0-9]  
     w  匹配字母、数字、下划线,等价于[a-zA-z0-9_]  word
    W  匹配非[^a-zA-z0-9_]  
    s  匹配任何空白字符(包括空格、制表符、换页符),等价于[ f v]  space
    S  匹配任何非空白字符(包括空格、制表符、换页符),等价于[^ f v]  
    转义字符  
    . 匹配除换行符( )之外的任何字符

     当一个字符类的开始或末尾处使用点号时,只能成为普通的点号字符

    []

    只能匹配一个字符,自带“或”的属性,后面可以跟修饰符。

    方括号内,个别字符有不同的含义:

      ^仅在作为第一个字符(方括号内)时,表明字符类取反

      - 标记字符范围

       转义字符

     
    () 包含一个子表达式,要表达“或”需要“|”  
    | 开始一个可选分支  

    分组元字符

    字符 说明 备注
    () 将表达式括起来,与其他元字符配合使用  

    引用

    字符 说明 备注
    & 在替换字符串中,符号&代表整个正则表达式所匹配的字符串的内容  仅在替换时使用
    (n=1,2...) 转移数字 代表索索字符串的第n个括号中正则表达式所匹配的字符串内容  查找、替换都能使用

    各元字符的优先级

    优先级 字符集 说明
    1 转义
    2 ^wd等  
    3 (),[]  
    4 *,+,?,{} 两次
    5 ^,$ 断言,位置
    6 | 分组

    PHP中正则相关的几个方法

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

       用途:返回值是匹配成功的次数0或者1,在匹配到1次以后就会停止搜索

       参数:$pattern 为正则表达式;$subject为被搜索的字符串;$matches可选,存储匹配结果的数组,$matches[0]包含整个模式匹配的文本,$matches[1]为第一个括号中的子模式所匹配的文本,依次类推

       代码示例:

    $subject = "abcdef";
    $pattern = '/a(.*)(w)d/';
    preg_match($pattern, $subject, $matches);
    print_r($matches); 
    

     返回结果:

      Array
      (
        [0] => abcd
        [1] => b
        [2] => c
      )  

    2.preg_match_all($pattern, $subject, $matches,$flags]); 

     用途:循环获取一个列表的匹配结果数组。

     参数:$pattern 为正则表达式;$subject为被搜索的字符串;

        $matches必选,存储匹配结果的多维数组

            $flags有多个值,int类型。

          case: flag=1,PREG_PARTTERN_ORDER   默认值,$matches[0]存储的是全部模式匹配的数组,$matches[1]为第一个括号中的子模式所匹配的文本array,依次类推。

    $p = "|<[^>]+>(.*?)</[^>]+>|i";
    $str = "<b>example: </b><div align=left>this is a test</div>";
    preg_match_all($p, $str, $matches,1);
    print_r($matches);
    

    运行结果:

    Array
    (
    [0] => Array
    (
    [0] => <br>example: </br>
    [1] =><div>this is a test</div>

    )
    [1] => Array
    (
    [0] => example: 
    [1] => this is a test
    )
    )  

          case: flag=2,PREG_SET_ORDER ,$matches[0]存储的是第一括号里面模式匹配的所有数组,$matches[1]为第而括号里面模式匹配的所有数组,依次类推。

       代码示例: 

    $p = "|<[^>]+>(.*?)</[^>]+>|i";
    $str = "<b>example: </b><div align=left>this is a test</div>";
    preg_match_all($p, $str, $matches,2);
    print_r($matches);
    

     运行结果:

    Array
    (
    [0] => Array
    (
    [0] => <br>example: </br>
    [1] => example:
    )

    [1] => Array
    (
    [0] =><div>this is a test</div>

    [1] => this is a test
    )

    )

    3.preg_replace($pattern, $replacement, $string); 

       用途:找到一个字符串匹配的子串,并交换子串之间的位置。

       参数:第一个参数表示正则表达式;第二个参数表示新的位置,$1 表示所以父正则表达式list的每个元素的第一个子元素;第三个参数表示源字符串。

       返回:$string

    $string = 'April 15, 2014;July 16, 2015';
    $pattern = '/(w+) (d+), (d+)/i';
    $replacement = '$3, ${1} $2';
    preg_match_all($pattern,$string,$matches,2);
    print_r($matches);
    echo preg_replace($pattern, $replacement, $string); 

    结果:

    Array
    (
    [0] => Array
    (
    [0] => April 15, 2014
    [1] => April
    [2] => 15
    [3] => 2014
    )
    
    [1] => Array
    (
    [0] => July 16, 2015
    [1] => July
    [2] => 16
    [3] => 2015
    )
    
    )
    2014, April 15;2015, July 16

    常用示例

    1.匹配邮箱:

      '/^[a-zA-z_-.]+@[a-zA-z_-.]+.[a-zA-z_-.]+$/'

    或 '/^[w-.]+@[w-.]+.[w-.]+$/'

      tips:在中括号末尾的的. 是不需要转移字符的,而在中括号外的.就一定要记得加上转义

    2. ^$间隔符加深理解:

    $str="abcdae";
    $p1='/^ab/';
    $p2='/^a$/';
    echo preg_match($p1,$str);//1
    echo preg_match($p2,$str);//0
    

    3.常用的一个注册页面的验证

     

     1 $user = array(
     2     'name' => 'spark1985',
     3     'email' => 'spark@imooc.com',
     4     'mobile' => '13312345678'
     5 );
     6 //进行一般性验证
     7 if (empty($user)) {
     8     die('用户信息不能为空');
     9 }
    10 if (strlen($user['name']) < 6) {
    11     die('用户名长度最少为6位');
    12 }
    13 //用户名必须为字母、数字与下划线
    14 if (!preg_match('/^w+$/i', $user['name'])) {
    15     die('用户名不合法');
    16 }
    17 //验证邮箱格式是否正确
    18 if (!preg_match('/^[w.]+@w+.w+$/i', $user['email'])) {
    19     die('邮箱不合法');
    20 }
    21 //手机号必须为11位数字,且为1开头
    22 if (!preg_match('/^1d{10}$/i', $user['mobile'])) {
    23     die('手机号不合法');
    24 }
    25 echo '用户信息验证成功';
    RegisterPage
  • 相关阅读:
    8.8总结
    8.4总结
    8.3总结
    题目分享H 二代目
    题目分享G 二代目
    题目分享E 二代目
    题目分享F 二代目
    题目分享D 二代目
    题目分享C 二代目
    题目分享Y
  • 原文地址:https://www.cnblogs.com/Mrs-cc/p/4571520.html
Copyright © 2020-2023  润新知