ความแตกต่างระหว่าง java.lang.String replace()
กับreplaceAll()
วิธีการอื่นที่ไม่ใช่ภายหลังใช้ regex คืออะไร สำหรับการทดแทนอย่างง่ายเช่นแทนที่.
ด้วย/
จะมีความแตกต่างหรือไม่?
ความแตกต่างระหว่าง java.lang.String replace()
กับreplaceAll()
วิธีการอื่นที่ไม่ใช่ภายหลังใช้ regex คืออะไร สำหรับการทดแทนอย่างง่ายเช่นแทนที่.
ด้วย/
จะมีความแตกต่างหรือไม่?
คำตอบ:
ในjava.lang.String
การreplace
ใช้วิธีการอย่างใดอย่างหนึ่งจะใช้เวลาคู่ของถ่านหรือคู่ของหนึ่งCharSequence
's (ซึ่ง String เป็น subclass ดังนั้นจึงจะใช้เวลาอย่างมีความสุขคู่ของสตริงของ) วิธีการจะเข้ามาแทนที่เกิดขึ้นทั้งหมดของถ่านหรือreplace
CharSequence
ในทางกลับกันString
อาร์กิวเมนต์ทั้งสองreplaceFirst
และreplaceAll
นิพจน์ทั่วไป (regex) การใช้ฟังก์ชั่นที่ไม่ถูกต้องสามารถนำไปสู่ข้อบกพร่องที่ลึกซึ้ง
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()
นอกเหนือจากที่ใช้ในภายหลัง regex
A:แค่ regex พวกเขาทั้งสองแทนที่ทั้งหมด :)
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html
PS:
นอกจากนี้ยังมีreplaceFirst()
(ซึ่งต้องใช้ regex)
CharSequence
คือ ทั้งreplace()
และreplaceAll()
"ทำงานกับCharSequence
" มันเป็นเรื่องที่replaceAll()
จะพิจารณาให้CharSequence
เป็นนิพจน์ปกติดังนั้นจึงมองหาไม้ขีดไฟ regexในขณะที่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()
เพราะก่อนรวบรวมรูปแบบ regex แล้วจับคู่ก่อนแทนที่ในที่สุดในขณะที่อดีตเพียงแค่ตรงกับอาร์กิวเมนต์ที่ให้ไว้และแทนที่
เนื่องจากเราทราบว่าการจับคู่รูปแบบ regex มีความซับซ้อนมากขึ้นและช้าลงจึงแนะนำให้เลือกreplace()
มากกว่าreplaceAll()
ทุกครั้งที่ทำได้
ตัวอย่างเช่นสำหรับการทดแทนอย่างง่ายเช่นที่คุณพูดถึงมันจะดีกว่าที่จะใช้:
replace('.', '\\');
แทน:
replaceAll("\\.", "\\\\");
หมายเหตุ: อาร์กิวเมนต์วิธีการแปลงข้างต้นขึ้นอยู่กับระบบ
Pattern.compile(...)
เนื้อหา / ส่วนในการใช้งานของพวกเขาดูเหมือนว่าreplace
ซับซ้อนน้อยกว่าเกี่ยวกับวิธีการกำหนด / ส่งอาร์กิวเมนต์แรก "\"
มันไม่จำเป็นต้อง นอกจากนี้ยังreplace
มีให้ตั้งแต่ Java 1.5
และreplaceAll
ตั้งแต่1.4
String replace(char oldChar, char newChar)
ส่งคืนสตริงใหม่ที่เป็นผลมาจากการแทนที่ oldChar ทั้งหมดที่เกิดขึ้นในสตริงนี้ด้วย newChar
String replaceAll(String regex, String replacement
แทนที่แต่ละสตริงย่อยของสตริงนี้ที่ตรงกับนิพจน์ทั่วไปที่กำหนดด้วยการแทนที่ที่กำหนด
ไม่เป็นความจริงที่ replace () จะทำงานได้เร็วกว่า replaceAll () เนื่องจากทั้งคู่ใช้รหัสเดียวกันในการนำไปใช้
Pattern.compile (regex) .matcher (นี้) .replaceAll (ทดแทน);
ตอนนี้คำถามคือเมื่อจะใช้แทนที่และเมื่อใดที่จะใช้ replaceAll () เมื่อคุณต้องการแทนที่สตริงย่อยด้วยสตริงย่อยอื่นโดยไม่คำนึงถึงตำแหน่งที่เกิดขึ้นในสตริงให้ใช้ replace () แต่ถ้าคุณมีการตั้งค่าหรือเงื่อนไขบางอย่างเช่นแทนที่เฉพาะสตริงย่อยที่จุดเริ่มต้นหรือจุดสิ้นสุดของสตริงให้ใช้ replaceAll () นี่คือตัวอย่างที่จะพิสูจน์จุดของฉัน:
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 ด้วย replaceAll สตริงการแทนที่จะถูกจัดการแตกต่างกันระหว่าง replace และ replaceAll ฉันคาดว่า [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 () ด้วย replaceAll ()
หัวข้อเก่าที่ฉันรู้ แต่ฉันเป็นคนใหม่ของ 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()
ทำงานในแบบที่คุณต้องการ
เพื่อเพิ่มเลือก "คำตอบที่ดีที่สุด" (และคนอื่น ๆ ที่เป็นเพียงที่ดีเช่น Suragch ของ) String.replace()
เป็นข้อ จำกัด โดยการแทนที่ตัวอักษรที่มีลำดับ (ซึ่งเป็นการดำเนินการCharSequence
) อย่างไรก็ตามString.replaceAll()
จะไม่ถูก จำกัด โดยการแทนที่อักขระตามลำดับเท่านั้น คุณสามารถแทนที่อักขระที่ไม่ต่อเนื่องได้ตราบใดที่นิพจน์ทั่วไปของคุณถูกสร้างขึ้นในลักษณะดังกล่าว
นอกจากนี้ (ที่สำคัญที่สุดและชัดเจนอย่างเจ็บปวด) replace()
สามารถแทนที่ค่าตามตัวอักษรเท่านั้น ในขณะที่replaceAll
สามารถแทนที่ลำดับ 'ชอบ' (ไม่จำเป็นต้องเหมือนกัน)
replace()
method ไม่ใช้รูปแบบ regex ในขณะที่replaceAll()
method ใช้รูปแบบ regex ดังนั้นการดำเนินการได้เร็วกว่าreplace()
replaceAll()
แทนที่ทำงานบนชนิดข้อมูลถ่าน แต่ replaceAll ทำงานบนสตริงประเภทข้อมูลและทั้งคู่จะแทนที่อาร์กิวเมนต์แรกทั้งหมดด้วยอาร์กิวเมนต์ที่สอง
str.replaceAll(regex, repl)
Pattern.compile(regex).matcher(str).replaceAll(repl)
ดังนั้นจึงมีค่าใช้จ่ายขนาดใหญ่ขึ้นอยู่กับปริมาณการใช้งาน