正则 : “正向预查” 与 “ 反(逆)向预查”

有如下一些字符:

[abccsds ]

[awefwe]

[ sfw ]

[ abwe ]

[ a b ab awf]

我想找出除了[ab 之外的其他东西。

我的第1反应是:

/\[[^ab].*?\]/

这是多么低级的错误,[]表示的是一个集合,在[后加上^表示匹配[]内的所有字符之外的字符

第2反应:

/\[[^(ab)].*?\]/

你以为放个()就是表示一个整体吗?在[]内是不起作用的

第3反应:

/\[!(ab).*?\]/

!号?哪来的?根本没这个符号单独使用表示非的,你以为这是php啊

第3反应:

/\[[^a][^b].*?\]/

开起来不错,但“ [awefwe]” 这个也匹配不上了,[^a][^b] 之间是或关系,你要将他们搞成且关系才可以

第4反应:

不是要搞成且关系吗,好办:

/\[[^a]&[^b].*?\]/

晕,胡编乱造,你家的正则里有&符号啊

第5反应:

怎么样才能把ab搞成一个整体呢?

要搞成整体,肯定要来个(),但决不能放到[]内,但符号^在[]内才能表示非啊

第6反应:

google ,翻半天没找到。

看php手册的正则表达式介绍,之前看过,但找半天没找到在哪。

看js手册里的介绍吧。

正则里面就 ?: ?= ?! 3个符号没用过,我要硬着头皮看明白

=====

?:

=====

还记得正则的后向引用吗?

比如匹配:

<?php

$str = 'zhangping234567890';

$str = preg_replace("/zhang(ping)(234)/","${1}1,$1", $str);

echo $str;

?>

可见我没有用到$2,但(234) 可能又出于某种需要,必须将其()起来,但又不想将其存储起来供以后使用,你只需改为(?:234)即可。

<?php

$str = 'zhangping234567890';

$str = preg_replace("/zhang(?:ping)(234)/","\${1}1,\$1", $str);

echo $str;

?>

=====

?=

=====

正向预查

比如:

有一个字符串:

abcdefghi

/ab(c)/ 将匹配出来abc 并将c储存到$1

/ab(?:c)/ 将匹配出来abc 并不会将c储存到$1

/ab(?=c)/ 将匹配出来ab,没有匹配出abc,那么c起什么作用呢,限定作用,解释器找到ab后没有马上返回,而是再查查ab后面的是c吗? 如果是c则才返回ab,否则返回匹配失败。看来它预查了c,难怪命名为正向预查。

我个人觉得这个匹配有个替代方法,可以去匹配/(ab)c/,然后通过$1取出ab,我觉得牛的是下面的这个符号!

=====

?!

=====

反(逆)向预查

=号变为了!号,!表示非,可见这是一个非操作,这个是否可以解决开始的问题呢?

比如:

有一个字符串:

abcdefghi

/ab(?=c)/ 将匹配出来后面紧跟着c的ab

推理:

/ab(?!c)/ 将匹配出来后面紧跟着不是c的ab,在这个字符串里,将匹配不出结果。

ok, 看看开始的问题是否能否解决。

要获取[后面不是ab的匹配,那么可以使用/\[(?!ab)/来匹配一个后面不是ab的[符号,

ok,这个确定后,再去匹配其他任何字符: /\[(?!ab).*?\]/

ok,问题解决。

发表回复