前一段时间在chinaunix论坛上发现这样一则问题:

要求abcd四个字母连续,但每个字母有且仅出现一次,并且顺序可以不固定,也就是要匹配abcd adbc bcda等等情况

我说一下自己的解决思路。

  • 第一个字母是abcd中的任意一个,因此正则式[abcd]即符合要求。第一个字母最简单。
  • 第二个字母是abcd中的任意一个,但是不能使用第一步中已经使用过的字母。因此回退一步,将第一个字母括起来,以备引用([abcd])。不能使用\1,亦即(?!\1),它表示当前位置不出现\1,即第一个字母。至此,正则式如下:([abcd])(?!\1)([abcd])
  • 第三个字母与第二个字母的原理相同,但是它既不能使用第一个字母,也不能使用第二个字母。正则式如下:([abcd])(?!\1)([abcd])(?!\1|\2)([abcd])
  • 第四步无需多言,完整正则式如下:([abcd])(?!\1)([abcd])(?!\1|\2)([abcd])(?!\1|\2|\3)([abcd])

回顾刚才的正则式,对于新手来说,或许(?!\1)是个不容易理解的地方。我就对此作用简单介绍。(?!...)的形式称为look around,与^$一样,它只匹配位置而不实际消耗字符。如果想匹配“某字串之后不出现某字串”这种情况,那么(?!)negative lookahead是不可缺少的。例如,如果想匹配q之后不出现u的字串,就可以使用q(?!u),它表示q后边不出现u。它可以匹配"Iraq","icq","qq"等字串。

如果您读到这里还没有头痛,请思考它与q[^u]的区别。