美文网首页
正则表达式之难点

正则表达式之难点

作者: 荆棘路上的猴子 | 来源:发表于2017-10-20 15:20 被阅读65次
    • 断言
    1. ?<= 这个是对需要匹配的目标左边的(前面)的进行断言,断定它前面会出现的 但是不会被匹配到。如:
    $subject = 'I am Lancer, Please say hello Lancer';
    
    //目标: 我要把hello 后面的Lancer  改为  '!' .
    $pattern = '/(?<=hello )Lancer/';
    $result = preg_replace($pattern, '', $subject);
    echo $result;  //I am Lancer, Please say hello !
    这样就成功咯~
    
    1. ?=,与上面的位置刚好相反,这个是对需要匹配的目标右边的(后面)的进行断言,断定它后面会出现的 但是不会被匹配到。如:
    $subject = 'I love you! I love her too!';
    
    //目标:不能爱这么多, 把第二个 'love' 改为 'hate'
    $pattern = '/love(?= her)/';
    $result = preg_replace($pattern, 'hate', $subject);
    echo $result;  //'I love you! I hate her too!'
    
    1. ?<!这个是需要对匹配左边的(前面的)进行断言,不过它是非,找到不是这个的。还是拿第一个例子来说:
    $subject = 'I am Lancer, Please say hello Lancer';
    
    //目标: 我还是要把hello 后面的Lancer  改为  '!'  该怎么做
    $pattern = '/(?<!am )Lancer/';  //找到‘Lancer’前面不是'am '的'Lancer'
    $result = preg_replace($pattern, '', $subject);
    echo $result;  //I am Lancer, Please say hello !
    
    1. ?!还是一样的秘方,还是一样的味道~
    $subject = 'I love you! I love her too!';
    
    //目标:不能爱这么多, 把第二个 'love' 改为 'hate'
    $pattern = '/love(?! you)/';
    $result = preg_replace($pattern, 'hate', $subject);
    echo $result;  //'I love you! I hate her too!'
    

    总结:这个断言,作用主要在,对于很多同样的目标,可是我只要其中的一个,或者多个的时候,那么就可以根据它的前面和后面,进行断言,来区分他们找到自己想要匹配的目标。

    • 捕获
      先来说一下, 什么叫捕获。就是匹配之后,会根据你正则表达式中的()来进行分组。一一捕获。打个比方:
    //为了显示方便,写了个show函数
    function show($str)
    {
        if (empty($str)) {
            echo null;
        } elseif (is_array($str) || is_object($str)) {
            echo '<pre>';
            print_r($str);
            echo '</pre>';
        } else {
            echo $str;
        }
    }
    //--------------------------------------------------------------------
    $subject  = '12323abcdea1233';
    $pattern = '/(a)(b)(c)(d)(e)/';
    preg_match_all($pattern, $subject, $matches);
    show($matches);
    //那么你会觉得 $matches 会是什么答案?
    //你肯定知道是:
    Array
    (
        [0] => Array
            (
                [0] => abcde
            )
    
        [1] => Array
            (
                [0] => a
            )
    
        [2] => Array
            (
                [0] => b
            )
    
        [3] => Array
            (
                [0] => c
            )
    
        [4] => Array
            (
                [0] => d
            )
    
        [5] => Array
            (
                [0] => e
            )
    
    )
    //这个答案,大家应该都知道吧。索引为0的是整个match的内容,接着的
    //就是捕获的每一个()分组的内容。我们还可以这样来写:
    
    $subject = '123abcabc123';
    $pattern = '/(a)(b)(c)(\1)(\2)(\3)/';
    preg_match_all($pattern, $subject, $matches);
    show($matches);//??
    先看答案:
    Array
    (
        [0] => Array
            (
                [0] => abcabc
            )
    
        [1] => Array
            (
                [0] => a
            )
    
        [2] => Array
            (
                [0] => b
            )
    
        [3] => Array
            (
                [0] => c
            )
    
        [4] => Array
            (
                [0] => a
            )
    
        [5] => Array
            (
                [0] => b
            )
    
        [6] => Array
            (
                [0] => c
            )
    
    )
    //你可能会有疑问, 咦,,, 怎么(\1)和(a), (\2)和(b),(\3)和(c) 在正则里是一样的呢?
    //其实 (a)就是指的第一组, 然后后面就可以用(\1)来表示。(b),(c)也一样。
    

    有人可能就会问了, 那你写这个的作用又是什么呢 ? 获取这些括号里的干啥。。 我只要第一个索引的匹配就够了呀。

    但是, 你考虑到了替换这个因素没? 如果我替换的时候需要()的东西呢? 这个时候,我们就可以用到捕获到的()的东西来穿插。

    不知道有人好奇过没,为什么用那些TP框架,Laravel框架, 或者smarty
    在模版里写的{{$msg}}为什么也能输出呢?
    其实就是用了正则替换~ 看代码:

    $msg = "正则捕获";
    $subject = '<p>{{$msg}}</p>';
    $pattern = '/\{\{(.*/)\}\}/';  //因为正则里也有'{' 和'}'所以需要用‘\’转义
    $result = preg_replace($pattern, '<?php echo $1; ?>', $subject);
    show($result); // <p><?php echo $msg;?></p> 
    //成功修改~
    

    上面说的是捕获, 但是我可能不想捕获怎么办? 那么就可以用(?:)
    在前面加上?:即可。注意, 这个不会影响匹配 只会影响捕获。
    如:

    $subject = 'abc';
    $pattern = '/(a)(?:b)(c)/';
    preg_match_all($pattern, $subject, $matches);
    show($matches);
    //结果:
    Array
    (
        [0] => Array
            (
                [0] => abc
            )
    
        [1] => Array
            (
                [0] => a
            )
    
        [2] => Array
            (
                [0] => c
            )
    )
    //看 匹配的结果让然是'abc' 不过没有捕获到 'b'
    

    以上就是基本的难点了, 纯手打和个人想法写完~ 谢谢观看,欢迎吐槽!

    相关文章

      网友评论

          本文标题:正则表达式之难点

          本文链接:https://www.haomeiwen.com/subject/tpqvuxtx.html