正则正/逆向预搜索不匹配……|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

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

正则表达式之贪婪匹配和非贪婪匹配

好吧,我透露下我最常用的正则手册地址吧,http://www.regexlab.com/zh/regref.htm。关于贪婪匹配和非贪婪匹配,今天群里面讨论得比较激烈。
贪婪模式:
在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:”{m,n}”, “{m,}”, “?”, “*”, “+”,具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 “dxxxdxxxd”,举例如下:

表达式 匹配结果
(d)(\w+) “\w+” 将匹配第一个 “d” 之后的所有字符 “xxxdxxxd”
(d)(\w+)(d) “\w+” 将匹配第一个 “d” 和最后一个 “d” 之间的所有字符 “xxxdxxx”。虽然 “\w+” 也能够匹配上最后一个 “d”,但是为了使整个表达式匹配成功,”\w+” 可以 “让出” 它本来能够匹配的最后一个 “d”

Continue reading

TP群中大P问的一个正则问题

大P<此算省略邮箱> 14:36:54
我需要一个正则
回复大P<此算省略邮箱> 14:36:56
首位不能是 /
所有字符不能包括 \<>*?:”|
不能包括 ./ 这个字符串

看来是目录正则匹配问题,还真是难倒了群里兄弟,呵呵,很久没接触正则表达式了,翻了下资料,初步确定要用预搜索,所以就简单了,

[^/]((?!\./)[^\\\<>\*\?:\"|](?<!\./))+

恩,解决了,推荐个正则参考资料:http://www.regexlab.com/zh/regref.htm正则工具的话用RegexBuddy,这个网上有破解版,你们懂的。

Editing and Testing Regular Expressions with RegExr

原文链接:http://www.webappers.com/2009/12/05/editing-and-testing-regular-expressions-with-regexr/

RegExr is an online tool for editing and testing Regular Expressions (RegExp / RegEx). It provides a simple interface to enter RegEx expressions, and visualize matches in real-time editable source text. It also provides a handy RegExp snippet sidebar with descriptions and usage examples to make it easier to learn Regular Expressions through trial and error.

RegExr is built with Flex 3, and uses ActionScript 3’s built in RegExp engine. It isn’t as powerful as a product like RegExBuddy, but it has the advantage of being online and free. You are able to save your patterns locally, and to share patterns on a searchable community database of regular expressions as well.

regular-expressions-tool

Demo: http://gskinner.com/RegExr/