正则啊正则

快被这几个正则给搞死了! 是用来匹配C语言中的/*…*/这样的注释,为了便于表示,将*替换为x,有以下三种方法:

/x([^x]|x+[^/])*x/

/x([^x]|x+[^/x])*x+/

/x[^x]*x+([^/x][^x]*x+)*/

第一个肯定是不对的,能够匹配过多的内容,比如 /xx A xx/ foo() /xx B xx/ .原因是,如果遇到…x/…, /迫使[^/]匹配了x,而下一轮迭代中的[^x]则正好可以匹配/,从而导致越过边界。 所以上边第二个正则中,使用[^/x]来迫使x+返还/前的所有x,这样可以达到匹配/x…x/的要求。

最后一个正则使用opening normal * (special normal *)* closing的形式,这样具有更高的匹配效率,首先匹配非x字符,然后是x,之后判断x之后是否为/,如果是,则结束匹配,否则进入下一轮special normal* 的循环。直到找到x后的/结束,完成匹配。

其实在第三个正则表达式中,最迷惑我的是special部分为什么用[^/x]而不是[^/],后来想了好久,发现[^/]和[^/x]的区别只发生在正则无法匹配字符串时,如果无法匹配,必然会迫使normal部分,即[^x]*x+,返还x,而返还的x正好可以被spcial部分的[^/]匹配,从而在无法匹配时造成无休止的循环。 使用[^/x]则避免了这个问题,可以立即报告匹配结束。

在实际应用中,需将x替换为*,以第三个为例,最终的正则表达式应该是

/\*[^*]*\*+(?:[^/*][^*]*\*+)*\*/

需要说明的是,如果你的正则引擎支持忽略优先量词,这样写是很傻逼的,直接用

/\*.*?\*/

就搞定了。

Related

Comments (3)

疾风December 10th, 2009 at 4:24 pm

我再三决定,不把这个软沙发留给任何人~·······

[Reply]

tomDecember 10th, 2009 at 9:53 pm

我决定,不把这个板凳留个任何人…

[Reply]

开心凡人December 11th, 2009 at 12:03 am

逛呀逛,拜访到这啦呵呵

[Reply]

Leave a comment

Your comment