String.replace: примеры (JAVA)

Примеры применения String.replace в Java
Раздел: Строки (String) - преобразование
String.replace(char oldChar, char newChar): String

Общее описание метода

В Java метод String.replace выполняет замену подстрок в строке и представлен двумя перегруженными версиями:

  • String replace(char oldChar, char newChar) - заменяет все вхождения символа oldChar на символ newChar.
  • String replace(CharSequence target, CharSequence replacement) - заменяет все вхождения последовательности символов target на replacement. В реализации используется буквальное сравнение (без регулярных выражений).

Возвращаемое значение в обоих случаях - новая строка (String) с выполненными заменами. Исходная строка остается неизменной, поскольку String в Java неизменяем.

Особенности аргументов и поведения:

  • Если oldChar не найден, возвращается исходная строка (возможно тот же объект, оптимизация может вернуть тот же экземпляр).
  • Если target равен пустой строке, поведение у перегрузки с CharSequence - все места между символами и начало/конец считаются местами вхождения; замена вставит replacement между символами (обычно такое поведение редко требуется).
  • Если аргумент target или replacement равен null, генерируется NullPointerException.
  • Метод replace с CharSequence работает по буквальному соответствию. Для шаблонных замен по регулярным выражениям служат методы replaceAll и replaceFirst, которые принимают regex.
  • Поддерживаются все реализации CharSequence (например, StringBuilder, StringBuffer), они автоматически приводятся к строке при сравнении.

Резюме: String.replace подходит для простых буквальных замен символов или подстрок. Для регулярных выражений используются другие методы.

Короткие примеры использования

Примеры показывают код и результат.

1) Замена символов (char → char)

String s = "java";
String r = s.replace('a', 'o');
System.out.println(r);
jovo

2) Замена подстрок (CharSequence → CharSequence)

String s = "abracadabra";
String r = s.replace("abra", "x");
System.out.println(r);
xcadx

3) Если целевая подстрока отсутствует

String s = "hello";
String r = s.replace("z", "q");
System.out.println(r);
hello

4) Отличие от replaceAll (replace - буквальная замена, replaceAll - по regex)

String s = "a1b2";
String r1 = s.replace("\d", "#");       // буквальная замена \d не найдена
String r2 = s.replaceAll("\\d", "#"); // regex: цифры заменены
System.out.println(r1);
System.out.println(r2);
a1b2
a#b#

5) Передача CharSequence (например, StringBuilder)

StringBuilder sb = new StringBuilder("xx");
String s = "xx yy xx";
String r = s.replace(sb, new StringBuilder("zz"));
System.out.println(r);
zz yy zz

Аналоги и похожие методы в Java

Краткое перечисление альтернатив и их назначение.

  • String.replaceAll(String regex, String replacement) - замены по регулярному выражению; подходит при сложных шаблонах, но требует экранирования метасимволов.
  • String.replaceFirst(String regex, String replacement) - заменяет только первое вхождение по regex.
  • java.util.regex.Pattern и Matcher - для сложных сценариев динамических замен и использования групп, доступа к MatchResult и поэтапного формирования строки с appendReplacement/appendTail.
  • StringBuilder.replace(int start, int end, String str) - выполняет замену по индексам в изменяемом буфере; предпочтительнее при множественных по позициям изменениях ради производительности.
  • Apache Commons Lang StringUtils.replace - удобные утилиты: безопаснее при null, есть версии с заменой ограниченного числа вхождений.

Когда использовать что:

  • Для простых буквальных замен - String.replace.
  • Для шаблонных замен - replaceAll или Matcher.
  • Для больших или частых изменений - StringBuilder или специализированные утилиты.

Аналоги в других языках и отличия

Короткие примеры для разных языков и ключевые отличия по сравнению с Java String.replace.

PHP - str_replace (буквально) и preg_replace (regex)

$s = 'abracadabra';
echo str_replace('abra', 'x', $s);
xcadx

JavaScript - String.prototype.replace (строка или RegExp)

let s = 'a1b2';
console.log(s.replace(/\d/g, '#')); // regex
console.log(s.replace('\d', '#'));  // буквально, не заменяет цифры
a#b#
a1b2

Python - str.replace(old, new[, count]) и re.sub

s = 'a1b2'
print(s.replace('1', 'X'))       # буквальная
import re
print(re.sub(r'\d', '#', s))    # regex
aXb2
a#b#

SQL - REPLACE(column, 'old', 'new') (буквально), некоторые СУБД поддерживают regexp_replace

-- пример в SQL
SELECT REPLACE('abracadabra', 'abra', 'x');
xcadx

C# - string.Replace(string oldValue, string newValue) (буквально) и перегрузки для char

string s = "hello";
Console.WriteLine(s.Replace('l', 'x'));
hexxo

Lua - string.gsub (по умолчанию поддерживает шаблоны Lua, не полноценный regex)

print((string.gsub('a1b2','%d','#')))
a#b#    2

Go - strings.Replace и strings.ReplaceAll

import "strings"
s := "a1b2"
fmt.Println(strings.ReplaceAll(s, "1", "X"))
aXb2

Kotlin - методы String.replace(oldValue, newValue) и String.replace(Regex, String) (совместимы с Java, есть дополнительные удобства).

val s = "abracadabra"
println(s.replace("abra", "x"))
xcadx

Отличия: в большинстве языков есть отдельные функции для буквальной и регулярной замены; в некоторых языках (C#, Kotlin) семантика очень близка к Java, в JS поведение зависит от того, передана ли строка или RegExp.

Типичные ошибки и их проявления

Частые ошибки при использовании и примеры их результатов.

1) Ожидание изменения исходной строки (ошибка: String неизменяем)

String s = "hello";
s.replace('l', 'x');
System.out.println(s);
hello

Комментарий: метод возвращает новую строку; нужно присвоить результат, если требуется сохранить замену.

2) NullPointerException при передаче null для CharSequence

String s = "abc";
String r = s.replace(null, "x");
Exception in thread "main" java.lang.NullPointerException

3) Путаница с регулярными выражениями (ожидание, что replace работает как regex)

String s = "a1b2";
System.out.println(s.replace("\\d", "#")); // буквально ищет "\d"
a1b2

4) Ошибки с метасимволами в replacement при replaceAll (замена использует $1 для групп)

String s = "user$home";
String r = s.replaceAll("\\$home", "\\$ROOT");
System.out.println(r);
java.lang.IllegalArgumentException: Illegal group reference

Решение: использовать Matcher.quoteReplacement для безопасного replacement.

5) Некорректная работа при пустой целевой подстроке

String s = "abc";
System.out.println(s.replace("", "X"));
XaXbXcX

Комментарий: вставка между символами, обычно не ожидаемое поведение.

Изменения и история

Ключевые факты о развитии метода:

  • Перегрузка с char присутствует в Java с ранних версий; версия с CharSequence появилась в более поздних релизах платформы и давно доступна в современных JDK.
  • В последних версиях Java не было принципиальных изменений в семантике String.replace. Развитие функциональности шло в сторону улучшений API для регулярных выражений и класса Matcher, а также оптимизаций производительности в реализации String и JIT-компилятора.
  • Для динамических и контекстных замен рекомендуется использовать Matcher с appendReplacement и appendTail, что является стабильным подходом во всех современных версиях.

Расширенные и редкие сценарии использования

Несколько более сложных примеров с пояснениями.

1) Динамическая замена по шаблону с обработкой групп (использование Matcher)

Пример java
import java.util.regex.*;

String s = "John:30, Mary:25";
Pattern p = Pattern.compile("(\\w+):(\\d+)");
Matcher m = p.matcher(s);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    String name = m.group(1);
    String age = m.group(2);
    m.appendReplacement(sb, name + "(" + age + ")");
}
m.appendTail(sb);
System.out.println(sb.toString());
John(30), Mary(25)

Пояснение: для составления результата с вычислениями используется appendReplacement.

2) Безопасная вставка текста, содержащего символы $ и \ (использование Matcher.quoteReplacement)

Пример java
String s = "path: $HOME";
String repl = "C:\\Users\\Name";
String r = s.replaceAll("\\$HOME", Matcher.quoteReplacement(repl));
System.out.println(r);
path: C:\Users\Name

3) Замена перекрывающихся вхождений через lookahead (пример с 'ana' в 'banana')

Пример java
String s = "banana";
String r = s.replaceAll("(?=(ana))ana", "X");
System.out.println(r);
bXna

Пояснение: стандартный поиск не всегда находит перекрывающиеся шаблоны; для этого применяются lookahead/lookbehind.

4) Массовые последовательные замены с высокой производительностью (использование StringBuilder)

Пример java
String s = "a".repeat(10000) + "b";
// если нужно заменить множество разных фрагментов в цикле, эффективнее собрать результат в StringBuilder
StringBuilder sb = new StringBuilder(s);
int index = sb.indexOf("a");
while (index != -1) {
    sb.setCharAt(index, 'x');
    index = sb.indexOf("a", index + 1);
}
System.out.println(sb.substring(0, 5));
xxxxx

Комментарий: для большого количества замен по позициям изменение буфера эффективнее создания новых строк.

5) Замена шаблонов с условной логикой (через Matcher и вычисление replacement)

Пример java
Pattern p = Pattern.compile("(\\d+)");
Matcher m = p.matcher("Prices: 100 200 300");
StringBuffer out = new StringBuffer();
while (m.find()) {
    int v = Integer.parseInt(m.group(1));
    m.appendReplacement(out, String.valueOf(v * 2));
}
m.appendTail(out);
System.out.println(out.toString());
Prices: 200 400 600

Пояснение: для арифметики и других вычислений на основе найденных групп используется итерация по совпадениям.

джава String.replace function comments

En
String.replace Returns a string resulting from replacing all occurrences of oldChar in this string with newChar