Odpowiedzi:
W java.lang.StringThe replacemetoda albo trwa parę char lub parę CharSequence„s (z których String jest podklasą, więc ona szczęśliwie wziąć parę struny). replaceMetoda zastąpi wszystkie wystąpienia char lub CharSequence. Z drugiej strony oba Stringargumenty do replaceFirsti replaceAllsą wyrażeniami regularnymi (regex). Korzystanie z niewłaściwej funkcji może prowadzić do subtelnych błędów.
String#replace(target, replacement)robi to samo, tyle że cytuje ciągi znaków: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));czy istnieje jakiś powód, dla którego String#replacebyłoby szybsze niż String#replaceAll? Nie wyglądałoby na to, ponieważ String#replacepo prostu wykonuje dodatkowe operacje.
replaceAll. Odpowiedź brzmi bardziejreplace
P: Jaka jest różnica między java.lang.Stringmetodami replace()i replaceAll(), poza tym, że później używa wyrażenia regularnego.
Odp .: Po prostu regex. Oboje zastępują wszystko :)
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
PS:
Jest też replaceFirst()(który wymaga wyrażenia regularnego)
CharSequencejest. Zarówno replace()i replaceAll()„praca z CharSequence”. Jest tak, że replaceAll()traktuje podane CharSequencewyrażenie jako wyrażenie regularne, więc szuka dopasowań wyrażenia regularnego , podczas gdy replace()uważa podane CharSequencejako zwykły tekst wyszukiwania, więc szuka jego wystąpienia .
Zarówno replace()i replaceAll()zamień wszystkie wystąpienia w ciągu.
Zawsze znajduję przykłady pomocne w zrozumieniu różnic.
replace()Użyj, replace()jeśli chcesz po prostu zamienić niektóre na charinne charlub niektóre na Stringinne String(faktycznie CharSequence).
Przykład 1
Zastąpić wszystkie wystąpienia znaku xz 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_
Przykład 2
Zastąpić wszystkie wystąpienia napisu fishz 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()Użyj, replaceAll()jeśli chcesz użyć wzorca wyrażenia regularnego .
Przykład 3
Zamień dowolny numer na 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
Przykład 4
Usuń wszystkie białe znaki.
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
Dokumentacja
replace(char oldChar, char newChar)replace(CharSequence target, CharSequence replacement)replaceAll(String regex, String replacement)replaceFirst(String regex, String replacement)Wyrażenia regularne
replace()Metoda jest przeciążony do zaakceptowania zarówno prymitywne chari CharSequencejako argumenty.
Jeśli chodzi o wydajność, replace()metoda jest nieco szybsza niż replaceAll()dlatego, że ta ostatnia najpierw kompiluje wzorzec wyrażenia regularnego, a następnie dopasowuje przed ostatecznym zastąpieniem, podczas gdy pierwsza po prostu dopasowuje podany argument i zamienia.
Ponieważ wiemy, że dopasowanie regex wzorzec jest nieco bardziej skomplikowana, a co za tym idzie wolniej, a preferowanie replace()ponad replaceAll()sugeruje w miarę możliwości.
Na przykład w przypadku prostych zamian, takich jak wspomniane, lepiej użyć:
replace('.', '\\');
zamiast:
replaceAll("\\.", "\\\\");
Uwaga: powyższe argumenty metody konwersji zależą od systemu.
Pattern.compile(...)treści / części w swoich implementacjach, wydaje się, że replacejest mniej skomplikowane w zakresie definiowania / wysyłania pierwszego argumentu. To nie wymaga "\". Ponadto replacejest dostępny od Java 1.5i replaceAllod1.4
String replace(char oldChar, char newChar)
Zwraca nowy ciąg wynikający z zamiany wszystkich wystąpień oldChar w tym ciągu na newChar.
String replaceAll(String regex, String replacement
Zastępuje każdy podciąg tego łańcucha, który pasuje do podanego wyrażenia regularnego z podanym zamiennikiem.
Nie jest prawdą, że replace () działa szybciej niż replaceAll (), ponieważ oba wykorzystują ten sam kod w swojej implementacji
Pattern.compile (regex) .matcher (this) .replaceAll (replace);
Teraz pytanie brzmi: kiedy użyć replace i kiedy użyć replaceAll (). Jeśli chcesz zastąpić podciąg innym podciągiem, niezależnie od miejsca jego wystąpienia w ciągu, użyj replace (). Ale jeśli masz jakieś szczególne preferencje lub warunki, takie jak zamień tylko te podciągi na początku lub na końcu łańcucha, użyj replaceAll (). Oto kilka przykładów, które mogą potwierdzić mój punkt widzenia:
String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
replacenie dzwoni Pattern.compile(regex).matcher(this).replaceAll(replacement);. WzywaPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Jak wspomniano w odpowiedzi wickeD, z replaceAll ciąg zastępujący jest traktowany inaczej w zastępstwie i replaceAll. Oczekiwałem, że [3] i [4] będą miały tę samą wartość, ale są różne.
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());
}
}
Wynikiem tego jest:
\ 1
X 1
\X 2
X 1
\X 2
Różni się to od perla, w którym zamiana nie wymaga dodatkowego poziomu ucieczki:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
który drukuje \ X 2
Może to być dość uciążliwe, jak przy próbie użycia wartości zwracanej przez java.sql.DatabaseMetaData.getSearchStringEscape () z replaceAll ().
Stary wątek Wiem, ale jestem trochę nowy w Javie i odkryłem jedną z dziwnych rzeczy. Użyłem, String.replaceAll()ale otrzymuję nieprzewidywalne wyniki.
Coś w stylu bałaganu:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
Więc zaprojektowałem tę funkcję, aby obejść ten dziwny problem:
//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;
}
Które sprawiają, że możesz zrobić:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
String.replaceAll()oczekuje wyrażeń regularnych, a nie dosłownych argumentów, dlatego otrzymujesz wyniki „nieprzewidywalne” (które są naprawdę bardzo przewidywalne). String.replace()działa tak, jak chcesz.
Aby dodać do już wybranej „najlepszej odpowiedzi” (i innych, które są tak samo dobre jak Suragch), String.replace()ogranicza się zastępowanie znaków, które są sekwencyjne (w ten sposób przyjmując CharSequence). Nie String.replaceAll()jest jednak ograniczany przez zamianę tylko znaków sekwencyjnych. Można zastąpić znaki niesekwencyjne, o ile wyrażenie regularne jest zbudowane w taki sposób.
Również (co najważniejsze i boleśnie oczywiste) replace()może jedynie zastąpić wartości dosłowne; podczas gdy replaceAllmoże zastąpić sekwencje „podobne” (niekoniecznie identyczne).
replace()metoda nie używa wzorca wyrażenia regularnego, podczas gdy replaceAll()metoda używa wzorca wyrażenia regularnego. Więc replace()działa szybciej niż replaceAll().
replace działa na typie danych char, ale replaceAll działa na typie danych String i oba zastępują wszystkie wystąpienia pierwszego argumentu drugim argumentem.
str.replaceAll(regex, repl)jest takie samo jakPattern.compile(regex).matcher(str).replaceAll(repl). Jest więc duży narzut w zależności od tego, ile zużywa się.