Как вы используете границу слова Java с апострофами? - PullRequest
1 голос
/ 22 января 2011

Я пытаюсь удалить все вхождения слова в списке, но у меня возникают проблемы, когда в словах есть апострофы.

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);

output:
has a bike and 's bike is red

То, что я хочу, это:
has a bike and bob's bike is red

У меня ограниченное понимание регулярных выражений, поэтому я предполагаю, что есть решение, но мне сейчас недостаточно для создания регулярного выражения для обработки апострофов,Также я хотел бы, чтобы он работал с тире, чтобы фраза the new mail is e-mail заменяла только первое вхождение почты.

Ответы [ 2 ]

2 голосов
/ 22 января 2011

Все зависит от того, что вы понимаете под словом.Возможно, вам лучше определить, что вы понимаете, как разделитель слов: например, пробелы, запятые .... И напишите что-нибудь как

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, вы также можете сделать этот подвох: замените все вхождения ' на какую-нибудь букву Юникода, которая, как вы уверены, не появится в вашем тексте, а затем выполните обратную замену.Пример:

  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 позволяет указать согласованное поведение только в Юникоде, см. Например, здесь .

1 голос
/ 22 января 2011
\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().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...