स्ट्रिंग बदलें () और replaceAll () के बीच अंतर


221

Java.lang.String के तरीकों replace()और replaceAll()तरीकों के बीच अंतर क्या है, जो बाद में रेगेक्स का उपयोग करता है? जैसे साधारण प्रतिस्थापन के लिए, के .साथ बदलें / , क्या कोई अंतर है?

जवाबों:


174

में java.lang.String, replaceविधि या तो चार या जोड़ी की जोड़ी लेती है CharSequence(जिनमें से स्ट्रिंग एक उपवर्ग है, इसलिए यह खुशी से स्ट्रिंग की जोड़ी ले जाएगा)। replaceविधि एक चार या की सभी घटनाओं का स्थान ले लेगा CharSequence। दूसरी ओर, दोनों Stringतर्क replaceFirstऔर replaceAllनियमित अभिव्यक्ति (रेगेक्स) हैं। गलत फ़ंक्शन का उपयोग करने से सूक्ष्म कीड़े हो सकते हैं।


30
इसके अलावा, जावा डॉक्स के अनुसार, प्रत्येक कॉल str.replaceAll(regex, repl)समान है Pattern.compile(regex).matcher(str).replaceAll(repl)। तो एक बड़ा ओवरहेड है जो इस बात पर निर्भर करता है कि इसका कितना उपयोग किया जाता है।
user845279

4
@ user845279 यह दिलचस्प है कि आप कहेंगे कि चूंकि String#replace(target, replacement)वही काम करता है, सिवाय इसके कि वह तार को उद्धृत करता है: Pattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));क्या कोई कारण है कि String#replaceइससे तेज क्यों होगा String#replaceAll? ऐसा लगता है जैसे यह String#replaceसिर्फ अतिरिक्त संचालन करता है नहीं होगा ।
होरसे

1
बस जिज्ञासु, इस जवाब में जहां के खिलाफ स्पष्ट तुलना है replaceAll। इसका उत्तर और अधिक हैreplace
मैनुअल जॉर्डन

इसका मतलब रीप्लेक्स मैच की वजह से प्रतिस्थापन () महंगा होगा? है ना?
आश्चर्य है कि

98

प्रश्न:java.lang.String विधियों replace()और replaceAll(), जो बाद में रेगेक्स का उपयोग करता है, के बीच अंतर क्या है ।

A: बस regex। वे दोनों सभी की जगह लेते हैं :)

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

पुनश्च:

वहाँ भी है replaceFirst()(जो एक regex लेता है)


1
स्पष्टीकरण के लिए Thx कि यह केवल रेगीक्स है। मैं कैसे चाहता हूँ कि उन्होंने इसे प्रतिस्थापित किया था रिप्लेस रीगेक्स () की जगह
रिप्लाय

क्लैरिफिकेशन: रिप्लेसमेंट () रेग्युलर एक्सप्रेशंस के साथ काम करता है, रिप्लेस () चारसैलेंस के साथ काम करता है
जॉनी फाइव

2
@ जॉनीफाइव जो इसे और अधिक भ्रमित करता है। नियमित अभिव्यक्ति एक प्रकार नहीं है, CharSequenceहै। दोनों replace()और replaceAll()"साथ काम CharSequence"। यह replaceAll()माना जाता है कि दिए गए CharSequenceको एक नियमित अभिव्यक्ति के रूप में माना जाता है, इसलिए यह रेगेक्स मैचों की तलाश करता है , जबकि replace()दिए गए CharSequenceको एक सादे खोज पाठ के रूप में मानता है इसलिए यह इसके होने की घटनाओं को देखता है।
शांतिबेल 10

43

दोनों 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

किसी भी संख्या को a से बदलें 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

यह सभी देखें

प्रलेखन

नियमित अभिव्यक्ति


34

replace()विधि दोनों एक आदिम स्वीकार करने के लिए ओवरलोड हो गया है charऔर एक CharSequenceतर्क के रूप में।

अब जहां तक ​​प्रदर्शन का संबंध है, replace()विधि थोड़ी तेज है replaceAll()क्योंकि बाद में पहले रेगेक्स पैटर्न को संकलित किया जाता है और फिर अंत में बदलने से पहले मेल खाता है, जबकि पूर्व बस प्रदान किए गए तर्क और प्रतिस्थापन के लिए मेल खाता है।

चूंकि हम जानते हैं regex पैटर्न मिलान में थोड़ा और अधिक जटिल है और इसके फलस्वरूप धीमी है, तो पसंद करते हैं replace()अधिक replaceAll()जब भी संभव हो सुझाव दिया है।

उदाहरण के लिए, आपके द्वारा बताए गए सरल प्रतिस्थापनों के लिए, इसका उपयोग करना बेहतर है:

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

के बजाय:

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

नोट: उपरोक्त रूपांतरण विधि तर्क प्रणाली-निर्भर हैं।


6
यहां तक ​​कि बदलें भी ऐसा ही करें, जावा स्ट्रिंग डॉक्स से: पब्लिक स्ट्रिंग रिप्लेस (चारसेंसेन्स टारगेट, सस्पेंस रिप्लेसमेंट) {रिटर्न पैटर्न.कॉमपाइल (लक्ष्य.टोस्ट्रिंग (), पैटर्न.लिट्रल) .मैचेर (यह) .replaceAll (Matcher.quoteReplacement)। (replacement.toString ())); }
प्रेटेक

@Prateek: jdk8 के बाद, स्ट्रिंग :: प्रतिस्थापित अब पैटर्न का उपयोग नहीं कर रहा है: hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a309408/src/… , jdk11 में समान।
फ्रेंक

सहमत हूँ, जावा 8 में व्यावहारिक रूप से दोनों विधियाँ लगभग समान हैं, क्योंकि दोनों Pattern.compile(...)अपने कार्यान्वयन में सामग्री / भाग को प्रदर्शित करते हैं , लगता replaceहै कि पहले तर्क को कैसे परिभाषित / प्रेषित किया जाए, इसके बारे में कम जटिल है। इसकी आवश्यकता नहीं है "\"। इसके अलावा replaceजावा 1.5और replaceAllतब से उपलब्ध है1.4
मैनुअल जॉर्डन

3
String replace(char oldChar, char newChar)

नए तार में पुराने तार की सभी घटनाओं को बदलने के परिणामस्वरूप एक नया स्ट्रिंग देता है।

String replaceAll(String regex, String replacement

इस स्ट्रिंग के प्रत्येक प्रतिस्थापन को प्रतिस्थापित करता है जो दिए गए प्रतिस्थापन के साथ दिए गए नियमित अभिव्यक्ति से मेल खाता है।


3
  1. दोनों () और रिप्लेसमेंट (सभी) दो तर्कों को स्वीकार करते हैं और पहले विकल्प (प्रथम तर्क) की सभी घटनाओं को दूसरे स्ट्रिंग (दूसरे तर्क) के साथ एक स्ट्रिंग में बदल देते हैं।
  2. प्रतिस्थापित () चार या वर्णक्रम की एक जोड़ी को स्वीकार करता है और प्रतिस्थापन () regex की एक जोड़ी को स्वीकार करता है।
  3. यह सच नहीं है कि प्रतिस्थापन () रिप्लेसमेंट की तुलना में तेजी से काम करता है () क्योंकि दोनों इसके कार्यान्वयन में समान कोड का उपयोग करते हैं

    Pattern.compile (regex) .matcher (यह) .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?"

4
वे सटीक समान कार्यान्वयन नहीं हैं। replaceफोन नहीं करता है Pattern.compile(regex).matcher(this).replaceAll(replacement);। यह कॉल करता हैPattern.compile(target.toString(), Pattern.LITERAL).matcher(this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
चीफट्वोन्फिल्स

ReplaceAll () regex की एक जोड़ी को स्वीकार करता है खोज स्ट्रिंग और प्रतिस्थापन स्ट्रिंग दोनों एक regex क्यों होगा ? क्या घटनाओं के साथ प्रतिस्थापित किया जाएगा? रेगेक्स के साथ? बेशक केवल पहला तर्क एक रेगेक्स (खोज स्ट्रिंग) है। दूसरा एक रेगेक्स (प्रतिस्थापन स्ट्रिंग) नहीं है।
सेंटीबैलर्स

1

जैसा कि wickeD के उत्तर में दिया गया है, प्रतिस्थापन के साथ प्रतिस्थापन स्ट्रिंग को प्रतिस्थापित और प्रतिस्थापन के बीच अलग-अलग संभाला जाता है। मुझे उम्मीद थी कि [3] और [४] का मूल्य समान होगा, लेकिन वे भिन्न हैं।

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

यह पर्ल से अलग है जहां प्रतिस्थापन को भागने के अतिरिक्त स्तर की आवश्यकता नहीं होती है:

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

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

जो \ X 2 प्रिंट करता है

यह काफी उपद्रव हो सकता है, जब बदले में java.sql.DatabaseMetaData.getSearchStringEscape () withAll () द्वारा दिए गए मान का उपयोग करने का प्रयास किया जाता है।


0

पुराना धागा जो मुझे पता है, लेकिन मैं जावा के लिए नया हूं और यह अजीब चीजों में से एक है। मैंने उपयोग किया है 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 );

1
String.replaceAll()अपेक्षा करता है कि नियमित अभिव्यक्तियाँ शाब्दिक तर्क न हों, यही कारण है कि आपको "अप्रत्याशित" (जो वास्तव में बहुत अधिक अनुमानित हैं) परिणाम मिलते हैं। String.replace()अपनी इच्छानुसार काम करता है।
नादर

जब हम जावा से अनपेक्षित परिणाम प्राप्त करते हैं, तो इसके लिए एक नए फ़ंक्शन को डिज़ाइन करने के बजाय अंगूठे के एक नियम के रूप में, यह मान लेना बेहतर है कि वे परिणाम सही हैं और हम जावा कार्यक्षमता का गलत उपयोग कर रहे हैं।
संटीबैलर्स

0

पहले से चयनित "सर्वश्रेष्ठ उत्तर" में जोड़ने के लिए (और अन्य जो कि सुरगच की तरह ही अच्छे हैं), String.replace()अनुक्रमिक (इस प्रकार लेने वाले CharSequence) वर्णों को बदलने से विवश है । हालांकि, String.replaceAll()केवल अनुक्रमिक वर्णों को बदलने से विवश नहीं है। आप गैर-अनुक्रमिक पात्रों को बदल सकते हैं और साथ ही जब तक आपकी नियमित अभिव्यक्ति इस तरह से बनाई जाती है।

इसके अलावा (सबसे महत्वपूर्ण और दर्दनाक रूप से स्पष्ट), replace()केवल शाब्दिक मूल्यों को बदल सकता है; जबकि replaceAll'की तरह' दृश्यों की जगह (जरूरी नहीं कि समान हो)।


-1

replace()विधि रेगेक्स पैटर्न का उपयोग नहीं करती है जबकि replaceAll()विधि रेगेक्स पैटर्न का उपयोग करती है। इसलिए replace()तेजी से प्रदर्शन करता है replaceAll()


3
यह सच नहीं है। यदि आप प्रतिस्थापन के स्रोत को देखेंगे तो देखेंगे कि इसमें पैटर्न और
माचिस

-5

कार्य को चार डेटा प्रकार पर प्रतिस्थापित करता है लेकिन सभी स्ट्रिंग स्ट्रिंगैट पर कार्य करता है और दोनों पहले तर्क की सभी घटनाओं को दूसरे तर्क के साथ प्रतिस्थापित करते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.