Відповіді:
У java.lang.String
, replace
метод або бере пару знаків або пару CharSequence
s (з яких String є підкласом, тому він із задоволенням візьме пару String's). replace
Метод замінить всі входження напівкоксу або CharSequence
. З іншого боку, обидва String
аргументи до replaceFirst
та replaceAll
є регулярними виразами (регулярні вирази). Використання неправильної функції може призвести до тонких помилок.
String#replace(target, replacement)
робить те ж саме, за винятком цитування рядків: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Чи є якась причина, чому String#replace
було б швидше, ніж String#replaceAll
? Здавалося б, не так, оскільки він String#replace
виконує додаткові операції.
replaceAll
. Відповідь детальніше проreplace
З: Яка різниця між java.lang.String
методами replace()
та replaceAll()
, окрім того, що пізніше використовується регулярний вираз.
A: Просто виразка. Вони обидва замінюють усіх :)
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
PS:
Існує також replaceFirst()
(що займає регулярний вираз)
CharSequence
є. І те, replace()
і replaceAll()
«працювати з CharSequence
». Це те, що replaceAll()
розглядає поданий CharSequence
як регулярний вираз, тому він шукає збіги регулярних виразів , тоді як replace()
розглядає дані CharSequence
як звичайний текст пошуку, тому він шукає його події .
Обидва replace()
і replaceAll()
замінюють усі події в рядку.
Я завжди вважаю приклади корисними для розуміння відмінностей.
replace()
Використовуйте, replace()
якщо ви просто хочете замінити деякі char
на інші char
або інші String
на інші String
(насправді CharSequence
).
Приклад 1
Замініть всі події персонажа x
на o
.
String myString = "__x___x___x_x____xx_";
char oldChar = 'x';
char newChar = 'o';
String newString = myString.replace(oldChar, newChar);
// __o___o___o_o____oo_
Приклад 2
Замініть всі входження рядка fish
на sheep
.
String myString = "one fish, two fish, three fish";
String target = "fish";
String replacement = "sheep";
String newString = myString.replace(target, replacement);
// one sheep, two sheep, three sheep
replaceAll()
Використовуйте, replaceAll()
якщо ви хочете використовувати шаблон звичайного вираження .
Приклад 3
Замініть будь-яке число на x
.
String myString = "__1_6____3__6_345____0";
String regex = "\\d";
String replacement = "x";
String newString = myString.replaceAll(regex, replacement);
// __x_x____x__x_xxx____x
Приклад 4
Видаліть все пробіли.
String myString = " Horse Cow\n\n \r Camel \t\t Sheep \n Goat ";
String regex = "\\s";
String replacement = "";
String newString = myString.replaceAll(regex, replacement);
// HorseCowCamelSheepGoat
Документація
replace(char oldChar, char newChar)
replace(CharSequence target, CharSequence replacement)
replaceAll(String regex, String replacement)
replaceFirst(String regex, String replacement)
Регулярні вирази
replace()
Метод перевантажений , щоб прийняти як примітивний char
і в CharSequence
якості аргументів.
Що ж стосується продуктивності, replace()
метод трохи швидший, ніжreplaceAll()
через те, що останній спочатку компілює шаблон регулярного вираження, а потім відповідає перед остаточною заміною, тоді як перший просто відповідає поданому аргументу та замінює.
Оскільки ми знаємо , що узгодження регулярних виразів шаблону є трохи більш складним і , отже , повільніше, потім віддаючи перевагу replace()
більшreplaceAll()
пропонується щоразу , коли це можливо.
Наприклад, для простих замін, як ви згадали, краще використовувати:
replace('.', '\\');
замість:
replaceAll("\\.", "\\\\");
Примітка: наведені вище аргументи методу перетворення залежать від системи.
Pattern.compile(...)
вміст / частина в їх реалізації, здається replace
, менш складний щодо визначення / відправки першого аргументу. Це не вимагає "\"
. Крім того replace
, доступний з Java 1.5
та replaceAll
з1.4
String replace(char oldChar, char newChar)
Повертає новий рядок, що виникає в результаті заміни всіх входжень oldChar у цій рядку на новийChar.
String replaceAll(String regex, String replacement
Замінює кожну підрядку цього рядка, яка відповідає заданому регулярному виразу із заданою заміною.
Це неправда, що substitu (працює) швидше, ніж substituAll (), оскільки обидва використовують один і той же код у своїй реалізації
Pattern.compile (regex) .matcher (це) .replaceAll (заміна);
Тепер питання полягає в тому, коли використовувати заміну та коли використовувати замінуAll (). Коли ви хочете замінити підрядку на іншу підрядку, незалежно від місця її виникнення в рядку, використовуйте substitute (). Але якщо у вас є якісь особливі уподобання або умови, такі як замінити лише ці підрядки на початку або в кінці рядка, використовуйте substituAll (). Ось кілька прикладів, які підтверджують мою думку:
String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
replace
не дзвонить Pattern.compile(regex).matcher(this).replaceAll(replacement);
. ДзвінкиPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Як згадується у відповіді wickeD, за допомогою stringAll рядок заміни обробляється по-різному між заміною та заміною Все. Я очікував, що [3] і [4] матимуть однакове значення, але вони різні.
public static void main(String[] args) {
String[] a = new String[5];
a[0] = "\\";
a[1] = "X";
a[2] = a[0] + a[1];
a[3] = a[1].replaceAll("X", a[0] + "X");
a[4] = a[1].replace("X", a[0] + "X");
for (String s : a) {
System.out.println(s + "\t" + s.length());
}
}
Результатом цього є:
\ 1
X 1
\X 2
X 1
\X 2
Це відрізняється від perl, коли для заміни не потрібен додатковий рівень втечі:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
який друкує \ X 2
Це може бути дуже неприємно, як при спробі використовувати значення, повернене java.sql.DatabaseMetaData.getSearchStringEscape () з substituAll ().
Я знаю стару тему, але я щось нове для Java і відкриваю одну з дивних речей. Я звикString.replaceAll()
але отримую непередбачувані результати.
Щось таке, як цей плутанина в струні:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
Тому я створив цю функцію, щоб подолати дивну проблему:
//String.replaceAll does not work OK, that's why this function is here
public String strReplace( String s1, String s2, String s )
{
if((( s == null ) || (s.length() == 0 )) || (( s1 == null ) || (s1.length() == 0 )))
{ return s; }
while( (s != null) && (s.indexOf( s1 ) >= 0) )
{ s = s.replace( s1, s2 ); }
return s;
}
Що дозволяє вам зробити:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
String.replaceAll()
очікує регулярних виразів, а не буквальних аргументів, саме тому ви отримуєте "непередбачувані" (які насправді дуже передбачувані) результати. String.replace()
працює так, як вам хочеться.
Додавання до вже вибраного "Найкращого відповіді" (та інших, які так само хороші, як Сурагч), String.replace()
обмежується заміною символів, які є послідовними (таким чином, прийнятими CharSequence
). Однак,String.replaceAll()
не обмежується лише заміною послідовних символів. Ви можете замінювати непослідовні символи, а також, поки ваш регулярний вираз побудований таким чином.
Також (найголовніше і болісно очевидно), replace()
може замінити лише буквальні значення; тоді як replaceAll
можна замінити "схожі" послідовності (не обов'язково однакові).
replace()
метод не використовує шаблон регулярного вираження, тоді як replaceAll()
метод використовує шаблон регулярного вираження. Так replace()
виконує швидше, ніж replaceAll()
.
замінити роботи на тип даних char, але замінитиВсі працює на типі даних String і обидва заміняють усі випадки першого аргументу другим аргументом.
str.replaceAll(regex, repl)
ж, що іPattern.compile(regex).matcher(str).replaceAll(repl)
. Отже, великі накладні витрати залежать від того, наскільки він використовується.