Заменить все вхождения подстроки в строке - что более эффективно в Java? - PullRequest
10 голосов
/ 23 марта 2011

Мне известны два способа замены всех вхождений подстроки в строке.

Способ регулярного выражения (при условии, что "подстрока, подлежащая замене" не включает в себя специальное регулярное выражение)chars):

String regex = "substring-to-be-replaced" + "+";
Pattern scriptPattern = Pattern.compile(regex);
Matcher matcher = scriptPattern.matcher(originalstring);
newstring = matcher.replaceAll("replacement-substring");

Способ String.replace ():

newstring = originalstring.replace("substring-to-be-replaced", "replacement-substring");

Какой из этих двух способов более эффективен (и почему)?

Есть ли ещеэффективные способы, чем описанные выше два?

Ответы [ 5 ]

12 голосов
/ 23 марта 2011

String.replace() использует регулярное выражение внизу.

public String replace(CharSequence target, CharSequence replacement) {
      return Pattern.compile(target.toString(), Pattern.LITERAL)
             .matcher(this ).replaceAll(
               Matcher.quoteReplacement(replacement.toString()));
  }

Существуют ли более эффективные способы, чем описанные выше два?

Дано, что вы работаете с реализацией, поддерживаемой, например, массивом, а ненеизменный класс String (поскольку string.replace создает новую строку при каждом вызове).Например, StringBuilder.replace () .

Компиляция регулярного выражения приводит к значительным много накладным расходам, что очевидно при наблюдении исходного кода Pattern ,К счастью, Apache предлагает альтернативный подход в StringUtils.replace(), который в соответствии с исходным кодом (строка # 3732) является довольно эффективным.

2 голосов
/ 23 марта 2011

Вот исходный код из openjdk:

public String replace(CharSequence target, CharSequence replacement) {
    return Pattern.compile(target.toString(), Pattern.LITERAL).matcher(
       this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
}
1 голос
/ 23 марта 2011

Не выполняя ни профилирования, ни бенчмаркинга, я бы сказал, что вполне безопасно делать ставку на то, что если вам не нужна магия регулярных выражений, то издержки синтаксического анализатора регулярных выражений (который вы получите независимо от того, что памяти, а также использование процессора) стоит вам намного больше, чем вы можете получить на другом конце.

1 голос
/ 23 марта 2011

Вместо использования string s, которые являются неизменяемыми, используйте char массивы или какой-либо другой изменяемый тип (например, StringBuffer или StringBuilder).

0 голосов
/ 23 марта 2011

Разве вы не должны сравнивать replaceAll 2 раза? Однако для одного вызова это вряд ли будет измеримо. И сделаете ли вы миллионы сравнений?

Тогда я ожидал бы, что 'compile' будет быстрее, но только если вы не используете константу String без каких-либо шаблонных правил.

Где проблема в написании микро-теста? Или посмотрите источник.

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