Câu trả lời:
Trong đó java.lang.String
, replace
phương thức sẽ lấy một cặp char hoặc một cặp CharSequence
(trong đó String là một lớp con, vì vậy nó sẽ vui vẻ lấy một cặp String). Các replace
phương pháp sẽ thay thế tất cả các lần xuất hiện của một char hay CharSequence
. Mặt khác, cả hai String
đối số đến replaceFirst
và replaceAll
là biểu thức chính quy (regex). Sử dụng sai chức năng có thể dẫn đến các lỗi tinh vi.
String#replace(target, replacement)
điều tương tự, ngoại trừ nó trích dẫn các chuỗi: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Có một số lý do tại sao String#replace
sẽ nhanh hơn String#replaceAll
? Có vẻ như nó String#replace
chỉ thực hiện các hoạt động bổ sung.
replaceAll
. Câu trả lời là về nhiều hơnreplace
Q: Sự khác biệt giữa các java.lang.String
phương thức replace()
và replaceAll()
, ngoài điều đó là sử dụng regex sau này.
A: Chỉ là regex. Cả hai đều thay thế tất cả :)
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
Tái bút
Ngoài ra còn có một replaceFirst()
(có một regex)
CharSequence
là. Cả hai replace()
và replaceAll()
"làm việc với CharSequence
". Nó replaceAll()
coi cái được đưa ra CharSequence
như một biểu thức chính quy để nó tìm kiếm kết quả khớp chính tả , trong khi replace()
coi cái được đưa ra CharSequence
như một văn bản tìm kiếm đơn giản để nó tìm kiếm sự xuất hiện của nó.
Cả hai replace()
và replaceAll()
thay thế tất cả các lần xuất hiện trong Chuỗi.
Tôi luôn tìm thấy những ví dụ hữu ích để hiểu sự khác biệt.
replace()
Sử dụng replace()
nếu bạn chỉ muốn thay thế một số char
bằng một số khác char
hoặc một số String
khác String
(thực tế CharSequence
).
ví dụ 1
Thay thế tất cả các lần xuất hiện của nhân vật x
bằng 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_
Ví dụ 2
Thay thế tất cả các lần xuất hiện của chuỗi fish
bằng 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()
Sử dụng replaceAll()
nếu bạn muốn sử dụng một mẫu biểu thức chính quy .
Ví dụ 3
Thay thế bất kỳ số nào bằng một 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
Ví dụ 4
Xóa tất cả khoảng trắng.
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
Tài liệu
replace(char oldChar, char newChar)
replace(CharSequence target, CharSequence replacement)
replaceAll(String regex, String replacement)
replaceFirst(String regex, String replacement)
Biểu thức chính quy
Các replace()
phương pháp được quá tải để chấp nhận cả một nguyên thủy char
và một CharSequence
như các đối số.
Bây giờ, liên quan đến hiệu suất, replace()
phương thức này nhanh hơn một chút so với replaceAll()
lần đầu tiên sau đó biên dịch mẫu biểu thức chính quy và sau đó khớp trước khi cuối cùng thay thế trong khi phương thức trước chỉ đơn giản khớp với đối số được cung cấp và thay thế.
Vì chúng ta biết khớp mẫu regex phức tạp hơn một chút và do đó chậm hơn, nên việc ưu tiên replace()
hơn replaceAll()
được đề xuất bất cứ khi nào có thể.
Ví dụ, đối với các thay thế đơn giản như bạn đã đề cập, tốt hơn là sử dụng:
replace('.', '\\');
thay vì:
replaceAll("\\.", "\\\\");
Lưu ý: các đối số phương thức chuyển đổi ở trên phụ thuộc vào hệ thống.
Pattern.compile(...)
nội dung / phần trong các triển khai của chúng, dường như replace
ít phức tạp hơn về cách định nghĩa / gửi đối số đầu tiên. Nó không yêu cầu "\"
. Hơn nữa replace
có sẵn từ Java 1.5
và replaceAll
kể từ đó1.4
String replace(char oldChar, char newChar)
Trả về một chuỗi mới do thay thế tất cả các lần xuất hiện của oldChar trong chuỗi này bằng newChar.
String replaceAll(String regex, String replacement
Thay thế từng chuỗi con của chuỗi này khớp với biểu thức chính quy đã cho bằng thay thế đã cho.
Không đúng khi thay thế () hoạt động nhanh hơn thay thế All () vì cả hai đều sử dụng cùng một mã trong quá trình triển khai.
Pattern.compile (regex) .matcher (this) .replaceAll (thay thế);
Bây giờ câu hỏi là khi nào nên sử dụng thay thế và khi nào nên sử dụng thay thế All (). Khi bạn muốn thay thế một chuỗi con bằng một chuỗi con khác bất kể vị trí xuất hiện của nó trong chuỗi sử dụng thay thế (). Nhưng nếu bạn có một số ưu tiên hoặc điều kiện cụ thể như chỉ thay thế các chuỗi con ở đầu hoặc cuối chuỗi, hãy sử dụng thay thế All (). Dưới đây là một số ví dụ để chứng minh quan điểm của tôi:
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
không gọi Pattern.compile(regex).matcher(this).replaceAll(replacement);
. Nó gọiPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Như được đề cập trong câu trả lời của wickeD, với thay thếTất cả chuỗi thay thế được xử lý khác nhau giữa thay thế và thay thế. Tôi mong đợi [3] và [4] có cùng giá trị, nhưng chúng khác nhau.
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());
}
}
Đầu ra của nó là:
\ 1
X 1
\X 2
X 1
\X 2
Điều này khác với perl khi sự thay thế không yêu cầu thêm mức thoát:
#!/bin/perl
$esc = "\\";
$s = "X";
$s =~ s/X/${esc}X/;
print "$s " . length($s) . "\n";
in nào \ X 2
Điều này có thể khá phiền toái, vì khi cố gắng sử dụng giá trị được trả về bởi java.sql.DatabaseMetaData.getSearchStringEscape () với thay thế All ().
Chủ đề cũ tôi biết nhưng tôi là người mới đối với Java và khám phá một trong những điều kỳ lạ. Tôi đã sử dụng String.replaceAll()
nhưng nhận được kết quả không thể đoán trước.
Một cái gì đó như thế này làm rối tung chuỗi:
sUrl = sUrl.replaceAll( "./", "//").replaceAll( "//", "/");
Vì vậy, tôi đã thiết kế chức năng này để khắc phục vấn đề kỳ lạ:
//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;
}
Điều này khiến bạn có thể làm:
sUrl=this.strReplace("./", "//", sUrl );
sUrl=this.strReplace( "//", "/", sUrl );
String.replaceAll()
mong đợi các biểu thức chính quy không phải là đối số theo nghĩa đen, đó là lý do tại sao bạn nhận được kết quả "không thể đoán trước" (đó thực sự là rất nhiều dự đoán). String.replace()
hoạt động theo cách bạn muốn.
Để thêm vào "Câu trả lời hay nhất" đã được chọn (và những câu trả lời tương tự như của Suragch), String.replace()
bị hạn chế bằng cách thay thế các ký tự liên tiếp (do đó lấy CharSequence
). Tuy nhiên, String.replaceAll()
không bị hạn chế bằng cách chỉ thay thế các ký tự liên tiếp. Bạn có thể thay thế các ký tự không tuần tự cũng như biểu thức chính quy của bạn được xây dựng theo cách như vậy.
Ngoài ra (quan trọng nhất và rõ ràng đau đớn), replace()
chỉ có thể thay thế các giá trị theo nghĩa đen; trong khi đó replaceAll
có thể thay thế các chuỗi 'like' (không nhất thiết phải giống hệt nhau).
replace()
phương thức không sử dụng mẫu regex trong khi replaceAll()
phương thức sử dụng mẫu regex. Vì vậy, replace()
thực hiện nhanh hơn replaceAll()
.
thay thế hoạt động trên kiểu dữ liệu char nhưng thay thế All hoạt động trên kiểu dữ liệu chuỗi và cả hai thay thế tất cả các lần xuất hiện của đối số thứ nhất bằng đối số thứ hai.
str.replaceAll(regex, repl)
giống nhưPattern.compile(regex).matcher(str).replaceAll(repl)
. Vì vậy, có một chi phí lớn tùy thuộc vào mức độ sử dụng của nó.