你如何使用撇号的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()
正确地转义字符串 。