正则正/逆向预搜索不匹配……|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
果然是正则牛女,膜拜!!