Perbedaan antara String replace () dan replaceAll ()

221

Apa perbedaan antara java.lang.String replace()danreplaceAll() metode, selain menggunakan regex nanti? Untuk penggantian sederhana seperti, ganti .dengan / , apakah ada perbedaan?

Jijoy
sumber

Jawaban:

174

Dalam java.lang.String, replacemetode baik mengambil sepasang char atau sepasang CharSequence(yang String adalah subclass, sehingga dengan senang hati akan mengambil sepasang String). The replaceMetode akan mengganti semua kejadian dari char atau CharSequence. Di sisi lain, keduanya Stringargumen untuk replaceFirstdan replaceAllmerupakan ekspresi reguler (regex). Menggunakan fungsi yang salah dapat menyebabkan bug halus.

emilan
sumber
30
Selain itu, menurut java docs, setiap panggilan ke str.replaceAll(regex, repl)sama dengan Pattern.compile(regex).matcher(str).replaceAll(repl). Jadi ada overhead yang besar tergantung pada seberapa banyak digunakan.
user845279
4
@ user845279 Sangat menarik Anda akan mengatakan bahwa karena String#replace(target, replacement)melakukan hal yang sama, kecuali mengutip string: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));Apakah ada beberapa alasan mengapa String#replaceakan lebih cepat daripada String#replaceAll? Tampaknya tidak seperti itu karena String#replacehanya melakukan operasi tambahan.
Horsey
1
Hanya ingin tahu, dalam jawaban ini mana perbandingan eksplisit terhadap replaceAll. Jawabannya lebih lanjut tentangreplace
Manuel Jordan
ini berarti replaceAll () akan lebih mahal karena pertandingan regex?
heran
97

T: Apa perbedaan antara java.lang.Stringmetode replace()dan replaceAll(), selain itu nanti menggunakan regex.

A: Hanya regex. Mereka berdua mengganti semua :)

http://docs.oracle.com/javase/6/docs/api/java/lang/String.html

PS:

Ada juga replaceFirst()(yang membutuhkan regex)

paulsm4
sumber
1
Terima kasih untuk klarifikasi bahwa itu hanya regex. Bagaimana saya berharap mereka menamakannya replaceWithRegex () bukannya replaceAll ()
HopeKing
Klarifikasi: replaceAll () bekerja dengan ekspresi reguler, replace () bekerja dengan CharSequence
Johnny Five
2
@JohnnyFive Itu membuatnya lebih membingungkan. Ekspresi reguler bukan tipe, CharSequenceadalah. Keduanya replace()dan replaceAll()"bekerja dengan CharSequence". Itu yang replaceAll()menganggap diberikan CharSequencesebagai ekspresi reguler sehingga mencari kecocokan regex , sementara replace()menganggap diberikan CharSequencesebagai teks pencarian biasa sehingga mencari kemunculannya .
SantiBailors
43

Keduanya replace()dan replaceAll()ganti semua kemunculan dalam String.

Contohnya

Saya selalu menemukan contoh yang membantu untuk memahami perbedaan.

replace()

Gunakan replace()jika Anda hanya ingin mengganti beberapa chardengan yang lain charatau beberapa Stringdengan yang lain String(sebenarnyaCharSequence ).

Contoh 1

Ganti semua kemunculan karakter xdengan 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_

Contoh 2

Ganti semua kemunculan string fishdengan 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()

Gunakan replaceAll()jika Anda ingin menggunakan pola ekspresi reguler .

Contoh 3

Ganti nomor apa pun dengan 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

Contoh 4

Hapus semua spasi putih.

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

Lihat juga

Dokumentasi

Ekspresi Reguler

Suragch
sumber
34

The replace()metode kelebihan beban untuk menerima baik primitif chardan CharSequencesebagai argumen.

Sejauh menyangkut kinerja, replace()metode ini sedikit lebih cepat daripadareplaceAll() karena yang terakhir pertama mengkompilasi pola regex dan kemudian cocok sebelum akhirnya diganti sedangkan yang pertama hanya cocok untuk argumen yang diberikan dan diganti.

Karena kita tahu pencocokan pola regex sedikit lebih kompleks dan akibatnya lebih lambat, kemudian lebih memilih replace()lebih replaceAll()disarankan bila memungkinkan.

Misalnya, untuk penggantian sederhana seperti yang Anda sebutkan, lebih baik menggunakan:

replace('.', '\\');

dari pada:

replaceAll("\\.", "\\\\");

Catatan: argumen metode konversi di atas bergantung pada sistem.

Surender Thakran
sumber
6
Bahkan ganti juga melakukan hal yang sama, Dari string java docs :: public String replace (target CharSequence, penggantian CharSequence) {return Pattern.compile (target.toString (), Pattern.LITERAL) .matcher (ini) .replaceAll (Matcher.quoteReplacement (replacement.toString ())); }
Prateek
@Prateek: setelah jdk8, String :: replace tidak menggunakan Pola lagi: hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/… , sama di jdk11.
Franck
Setuju, Di Jawa 8 praktis kedua metode ini hampir sama, untuk keduanya muncul Pattern.compile(...)konten / bagian dalam implementasinya, tampaknya replacekurang kompleks tentang cara mendefinisikan / mengirim argumen pertama. Itu tidak membutuhkan "\". Selanjutnya replacetersedia sejak Jawa 1.5dan replaceAllsejak1.4
Manuel Jordan
3
String replace(char oldChar, char newChar)

Mengembalikan string baru yang dihasilkan dari mengganti semua kemunculan oldChar di string ini dengan newChar.

String replaceAll(String regex, String replacement

Ganti setiap substring dari string ini yang cocok dengan ekspresi reguler yang diberikan dengan penggantian yang diberikan.

S. Rahul
sumber
3
  1. Baik replace () dan replaceAll () menerima dua argumen dan menggantikan semua kemunculan substring pertama (argumen pertama) dalam sebuah string dengan substring kedua (argumen kedua).
  2. replace () menerima sepasang char atau charsequence dan replaceAll () menerima sepasang regex.
  3. Tidak benar bahwa replace () bekerja lebih cepat daripada replaceAll () karena keduanya menggunakan kode yang sama dalam implementasinya

    Pattern.compile (regex) .matcher (ini) .replaceAll (pengganti);

Sekarang pertanyaannya adalah kapan harus menggunakan replace dan kapan harus menggunakan replaceAll (). Ketika Anda ingin mengganti substring dengan substring lain terlepas dari tempatnya di string gunakan replace (). Tetapi jika Anda memiliki beberapa preferensi atau kondisi tertentu seperti hanya mengganti substring tersebut di awal atau akhir string, gunakan replaceAll (). Berikut ini beberapa contoh untuk membuktikan pendapat saya:

String str = new String("==qwerty==").replaceAll("^==", "?"); \\str: "?qwerty=="
String str = new String("==qwerty==").replaceAll("==$", "?"); \\str: "==qwerty?"
String str = new String("===qwerty==").replaceAll("(=)+", "?"); \\str: "?qwerty?"
Aarya
sumber
4
Mereka bukan implementasi yang sama persis. replacetidak menelepon Pattern.compile(regex).matcher(this).replaceAll(replacement);. PanggilannyaPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
ChiefTwoPencils
replaceAll () menerima sepasang regex. Mengapa string pencarian dan string pengganti menjadi suatu regex? Dengan kejadian apa akan diganti? Dengan regex? Tentu saja hanya argumen pertama yang merupakan regex (string pencarian). Yang kedua bukan regex (string pengganti).
SantiBailors
1

Seperti disinggung dalam jawaban wickeD, dengan replaceAll string pengganti ditangani secara berbeda antara replace dan replaceAll. Saya mengharapkan [3] dan [4] memiliki nilai yang sama, tetapi mereka berbeda.

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

Output dari ini adalah:

\   1
X   1
\X  2
X   1
\X  2

Ini berbeda dari perl di mana penggantian tidak memerlukan tingkat tambahan untuk melarikan diri:

#!/bin/perl
$esc = "\\";
$s = "X";

$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";

yang mencetak \ X 2

Ini bisa menjadi gangguan, seperti ketika mencoba menggunakan nilai yang dikembalikan oleh java.sql.DatabaseMetaData.getSearchStringEscape () dengan replaceAll ().

Keith Crews
sumber
0

Utas lama saya tahu tetapi saya agak baru di Jawa dan menemukan salah satu hal yang aneh. Saya telah menggunakan String.replaceAll()tetapi mendapatkan hasil yang tidak terduga.

Sesuatu seperti ini mengacaukan string:

sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");

Jadi saya merancang fungsi ini untuk mengatasi masalah aneh:

//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;
}

Yang membuat Anda bisa melakukan:

sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
Codebeat
sumber
1
String.replaceAll()mengharapkan ekspresi reguler bukan argumen literal, itulah sebabnya Anda mendapatkan hasil "tidak dapat diprediksi" (yang benar-benar sangat dapat diprediksi). String.replace()bekerja seperti yang Anda inginkan.
Nadar
Sebagai aturan praktis ketika kita mendapatkan hasil yang tidak terduga dari Java, daripada merancang fungsi baru untuk menyiasatinya, lebih baik untuk menganggap bahwa hasil itu benar dan bahwa kita salah memahami fungsi Java yang kita gunakan.
SantiBailors
0

Untuk menambahkan ke "Jawaban Terbaik" yang sudah dipilih (dan yang lainnya sama baiknya dengan Suragch), String.replace()dibatasi dengan mengganti karakter yang berurutan (dengan demikian mengambil CharSequence). Namun,String.replaceAll() tidak dibatasi dengan mengganti karakter berurutan saja. Anda dapat mengganti karakter yang tidak berurutan juga selama ekspresi reguler Anda dibuat sedemikian rupa.

Juga (yang paling penting dan sangat menyakitkan), replace()hanya dapat menggantikan nilai-nilai literal; sedangkan replaceAllbisa mengganti urutan 'suka' (belum tentu identik).

hfontanez
sumber
-1

replace()Metode tidak menggunakan pola regex sedangkan replaceAll()metode menggunakan pola regex. Jadi replace()kinerjanya lebih cepat daripada replaceAll().

seorang pria
sumber
3
itu tidak benar. Jika Anda melihat sumber dari pengganti Anda akan melihatnya juga menggunakan Pattern and Matcher (yaitu regex)
xtrakBandit
-5

ganti berfungsi pada tipe data char tetapi replaceAll bekerja pada String datatype dan keduanya menggantikan semua kemunculan argumen pertama dengan argumen kedua.

Pramod Kumar
sumber