你如何使用撇号的Java字边界?

我试图删除列表中所有出现的单词,但是当单词中有撇号时我遇到了麻烦。

String phrase="bob has a bike and bob's bike is red"; String word="bob"; phrase=phrase.replaceAll("\\b"+word+"\\b",""); System.out.println(phrase); 

输出:
has a bike and 's bike is red

我想要的是
has a bike and bob's bike is red

我对正则表达式的理解有限,所以我猜有一个解决方案,但我现在还不足以创建正则表达式来处理撇号。 此外,我希望它与破折号一起使用,因此the new mail is e-mail的短语只会替换第一次出现的邮件。

这一切都取决于你所说的是一个“词”。 也许你最好定义你理解为单词分隔符的东西:例如,空格,逗号….并写一些东西作为

 phrase=phrase.replaceAll("([ \\s,.;])" + Pattern.quote(word)+ "([ \\s,.;])","$1$2"); 

但是你必须另外检查字符串开头和结尾的事件。例如:

  String phrase="bob has a bike bob, bob and boba bob's bike is red and \"bob\" stuff."; String word="bob"; phrase=phrase.replaceAll("([\\s,.;])" + Pattern.quote(word) + "([\\s,.;])","$1$2"); System.out.println(phrase); 

打印这个

 bob has a bike , and boba bob's bike is red and "bob" stuff. 

更新:如果你坚持使用\b ,考虑到“单词边界”理解Unicode,你也可以做这个肮脏的伎俩:用你确定不会出现在文本中的某些Unicode字母替换'所有出现' ,然后做反向替换。 例:

  String phrase="bob has a bike bob, bob and boba bob's bike is red and \"bob\" stuff."; String word="bob"; phrase= phrase.replace("'","ñ").replace('"','ö'); phrase=phrase.replaceAll("\\b" + Pattern.quote(word) + "\\b",""); phrase= phrase.replace('ö','"').replace("ñ","'"); System.out.println(phrase); 

更新:总结下面的一些评论:人们会期望\w\b具有与“单词字符”相同的概念,就像几乎所有正则表达方言一样。 好吧,Java没有: \w考虑ASCII, \b考虑Unicode。 我同意,这是一个丑陋的不一致。

更新2:自Java 7(在注释中指出)以来, UNICODE_CHARACTER_CLASS标志允许指定一致的仅Unicode行为,请参见此处 。

 \b\S*(bob|mail)\S*\b 

小心误报,这可能比你想要的更多。 如果你需要不超过2个字符的“前缀”或“后缀”(可能是"'s""e-" ),请使用\S{0,2}而不是\S*

正则表达式说:

 \b # a word boundary \S* # any number of non-spaces ( # match group 1 (to enable a choice) bob|mail # "bob" or "mail" ) # end match group 1 \S* # any number of non-spaces \b # a word boundary 

所以,在Java中:

 phrase = phrase.replaceAll("\\b\\S*(bob|mail)\\S*\\b", ""); 

小心一些事情

 phrase = phrase.replaceAll("\\b" + word + "\\b", ""); 

那应该是

 phrase = phrase.replaceAll("\\b" + Pattern.quote(word) + "\\b", ""); 

因为只要word包含正则表达式元字符,你的正则表达式就会破坏,除非你事先使用Pattern.quote()正确地转义字符串 。