正则表达式之难点

  • 断言
  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 = '/(?
  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 '
';
        print_r($str);
        echo '
'; } 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 = '

{{$msg}}

'; $pattern = '/\{\{(.*/)\}\}/'; //因为正则里也有'{' 和'}'所以需要用‘\’转义 $result = preg_replace($pattern, '', $subject); show($result); //

//成功修改~

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

$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'

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

你可能感兴趣的:(正则表达式之难点)