正则正/逆向预搜索不匹配……|bbb|….|….

那天在群里面@TP新人 又提出一个正则问题,描述如下:

[武汉]TP新人(997****) 18:17:48

aaa|bbb|ccc|ddd 这个是字符串的结构

[武汉]TP新人(997****) 18:17:59

aaa bbb ccc [武汉]TP新人(9976121) 18:18:32

我现在 要 匹配 第一个和 第二个竖线 除了是 bbb 这种情况之外的所有情况 ddd 都是 可变的

[武汉]TP新人(997****) 18:18:55

aaa|bbb|ccc|ddd 这是 不匹配的

武汉]TP新人(997****) 18:19:04

aaa|bbbbbb|ccc|dddd 这是匹配的

[武汉]TP新人(997****) 18:19:26

......|bbb|....|.... 这是不匹配的

@伪造 同学最近一直苦练正则,大有长劲,自告奋勇前来解题,哈哈,不料此题确实很刁,难以找到思路。@TP新人 也说没思路,看到这么难的份上我就试试吧 :) 。我也想了好久,大概有半个小时吧,中途@觉醒 劝我休息(谢谢关心)。废话不多说,看我设计的正则吧,这里用到了正向预搜索和反向预搜索:

((?<!\|bbb)\|(?!bbb\|))(.*?)\|

放到PHP中试验:

<?php
//$str = 'aaa|bbb|ccc|ddd';
$str = 'aaa|bbbff|ccc|ddd';

$str2 = '';

$r = preg_match_all('/((?<!\|bbb)\|(?!bbb\|))+(.*?)\|/', $str, $matches);

if ($r) {
    $str2 = preg_replace('/((?<!\|bbb)\|(?!bbb\|))+(.*?)\|/', "$1", $str);
}

var_dump($r);

var_dump($str2);

结果如下,当=$str='aaa|bbbff|ccc|ddd'=时:

---------- Debug PHP 5.3.5 ----------
int(1)
string(11) "aaa|ccc|ddd"

当=$str='aaa|bbb|ccc|ddd'=时:

---------- Debug PHP 5.3.5 ----------
int(0)
string(0) ""

其实也不难,最后发现原来群里面@笑笑 才是正则表达式大牛,下面引用她的话:

笑笑<****@gmail.com> 2011-5-13 10:33:59

(?<=t)

逆序肯定环视,表示所在位置左侧能够匹配t

(?<!t)

逆序否定环视,表示所在位置左侧不能匹配t

(?=t)

顺序肯定环视,表示所在位置右侧能够匹配t

(?!t)

顺序否定环视,表示所在位置右侧不能匹配t

笑笑<****@gmail.com> 2011-5-13 10:34:17

(?<) (?) (?<!) (?!)

笑笑<****@gmail.com> 2011-5-13 10:34:43

正则就是环视,捕获

笑笑<****@gmail.com> 2011-5-13 10:34:50

如果这两个搞懂了,其它的就简单了

笑笑<****@gmail.com> 2011-5-13 10:37:11

好记的方法 带有<符号的都是判断左侧的,<符号不是箭头向左嘛 理解是往左判断的

笑笑<****@gmail.com> 2011-5-13 10:37:30

不带<箭头符号的 那就认为是按照正常顺序往右判断的,正则匹配正常顺序都是从左到右依次匹配的

笑笑<****@gmail.com> 2011-5-13 10:37:58

= 和 ! 用来区分 是和非, 或者就是 肯定还是否定,=是肯定,就是=后为真,也就是说=号后面表达式能匹配成功; !是否定,就是!后的表达式不能匹配成功

笑笑<****@gmail.com> 2011-5-13 10:38:23

? 有两种功能 一种就是你说的0-1次匹配,还有就是用在量词* 和 + 后 来区分惰性匹配和贪婪匹配

[长沙] 校长<roy@solarphp.cn> 2011-5-13 10:39:40

笑笑偷了我的笔记

笑笑<****@gmail.com> 2011-5-13 10:39:40

比如字符串: a1b2c3d

1、要匹配字母后面是数字2的字母

正则:[a-z](?=2)

结果:b

2、要匹配字母前面是数字2的字母

正则:(?<=2)[a-z]

结果:c

3、要匹配后面不是数字2的字母

正则:[a-z](?!2)

结果:a c d

4、要匹配前面不是数字2的字母

正则:(?<!2)[a-z]

结果:a b d

果然是正则牛女,膜拜!!