使用正则表达式匹配非单词字符但不是笑脸

时间:2011-09-19 01:17:21

标签: java regex regex-negation lookahead

我有一个Java程序,它应该从字符串中删除所有非字母字符,除非它们是笑脸,例如=)或=]或:P

很容易将对面与[a-zA-Z ]|=\)|=\]|:P匹配,但我无法弄清楚如何否定这个表达式。由于我使用的是String.replaceAll()函数,因此它必须是否定形式。

我相信问题的一部分可能来自于微笑通常是2个字符的事实,而且我一次只匹配1个字符?

有趣的是,replaceAll("(?![Tt])[Oo]","")删除了字母O的每次出现,即使在单词“to”中也是如此。这是否意味着我的replaceAll函数不了解正则表达式的前瞻性?它没有任何错误......

我最终使用

replaceAll("(?<![=:;])[\\]\\[\\(\\)\\/]","")
.replaceAll("[=:;](?![\\]\\[\\(\\)o0OpPxX\\/])","")
.replaceAll("[^a-zA-Z=:;\\(\\)\\[\\]\\/ ]","")

这是非常混乱但完美的工作。 The... quick! (brown) fox jump's over the[] lazy dog. :] =O ;X变为THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG :] =O ;X

修改:忽略该修复程序,请参阅下面接受的答案。

1 个答案:

答案 0 :(得分:4)

使用负向前瞻应该很容易。基本上,匹配将在(?!...)组内的正则表达式匹配的任何位置失败。如果前瞻不匹配(意味着下一个字符是不是笑脸的一部分的非字母字符),则应使用单个通配符(.)跟随负向前瞻以消耗字符。 / p>

编辑:显然我没有彻底测试我原来的正则表达式,你还需要.之后的负面观察,以确保你消耗的角色不是第二个角色笑容:

(?![a-zA-Z ]|=\)|=\]|:P).(?<!=\)|=\]|:P)

请注意,您可以通过使用眼睛和嘴巴的字符类来缩短正则表达式,例如:

[:=][\(\)\[\]]
  ^    ^-----mouth
  |--eyes