我有一个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
修改:忽略该修复程序,请参阅下面接受的答案。
答案 0 :(得分:4)
使用负向前瞻应该很容易。基本上,匹配将在(?!...)
组内的正则表达式匹配的任何位置失败。如果前瞻不匹配(意味着下一个字符是不是笑脸的一部分的非字母字符),则应使用单个通配符(.
)跟随负向前瞻以消耗字符。 / p>
编辑:显然我没有彻底测试我原来的正则表达式,你还需要.
之后的负面观察,以确保你消耗的角色不是第二个角色笑容:
(?![a-zA-Z ]|=\)|=\]|:P).(?<!=\)|=\]|:P)
请注意,您可以通过使用眼睛和嘴巴的字符类来缩短正则表达式,例如:
[:=][\(\)\[\]]
^ ^-----mouth
|--eyes