स्ट्रिंग से चार की सभी घटनाओं को हटा दें


311

मैं इसका उपयोग कर सकता हूं:

String str = "TextX Xto modifyX";
str = str.replace('X','');//that does not work because there is no such character ''

क्या Xजावा में एक स्ट्रिंग से चरित्र की सभी घटनाओं को हटाने का एक तरीका है ?

मैंने यह कोशिश की और वह नहीं है जो मैं चाहता हूं: str.replace('X',' '); //replace with space


3
क्या आपने एकल वर्ण स्ट्रिंग्स को बदलने का प्रयास किया है?
pet.m.murray.rust

जवाबों:


523

इसके बजाय तर्क (जैसे ) लेने वाले अधिभारCharSequence का उपयोग करने का प्रयास करें :Stringchar

str = str.replace("X", "");

2
पहला तर्क नियमित अभिव्यक्ति है, कभी-कभी यह अपेक्षित रूप से काम नहीं करेगा, खासकर अगर यह स्ट्रिंग उपयोगकर्ता इनपुट से आती है।
वबंजरार

9
@vsb: सच नहीं है। उस विशेष अधिभार के दोनों तर्क हैं CharSequencedocs.oracle.com/javase/7/docs/api/java/lang/…
ल्यूक

Xटाइप चार के मामले में क्या करना है ?
केएनयू

7
@Kunal: मुझे लगता है कि आपको toStringपहले इसकी आवश्यकता होगी । तो आपका कोड कुछ इस तरह दिखेगाstr = str.replace(yourChar.toString(), "");
ल्यूक

ध्यान दें कि आप यूनिकोड से बच सकते हैं, उदाहरण के लिए गैर हटाएं नहींstr = str.replace("\uffff", "");
जैम हैब्टलजेल

42

का उपयोग करते हुए

public String replaceAll(String regex, String replacement)

काम करेगा।

उपयोग होगा str.replace("X", "");

निष्पादित

"Xlakjsdf Xxx".replaceAll("X", "");

रिटर्न:

lakjsdf xx

6
रेगेक्स शायद इसके लिए ओवरकिल है जब तक कि आप जावा 1.4 का समर्थन करने के लिए प्रतिबंधित नहीं हैं - संस्करण 1.5 के बाद से एक replaceअधिभार है जो एक सरल लेता है CharSequence
ल्यूक

3
@ ल्यूक, यह String.replace को विघटित स्रोत है। यह regex का उपयोग कर रहा है। मैं मानता हूं कि यह रेगेक्स भारी लगता है, लेकिन यह है कि ऊपर दिए गए स्वीकृत उत्तर के लिए भी हुड के नीचे है। पब्लिक स्ट्रिंग रिप्लेस (CharSequence var1, CharSequence var2) {return pattern.compile (var1.toString (), 16) .matcher (यह) .replaceAll (Matcher.quoteRement (var2.toString ())); }
पेरी टव

24

यदि आप Java स्ट्रिंग्स के साथ कुछ करना चाहते हैं, तो Commons Lang StringUtils एक शानदार स्थान है।

StringUtils.remove("TextX Xto modifyX", 'X');

वास्तव में मैं क्या देख रहा था, शायद इसलिए कि यह अभी से अधिक स्पष्ट दिखता है replace
लाइन

6
String test = "09-09-2012";
String arr [] = test.split("-");
String ans = "";

for(String t : arr)
    ans+=t;

यह वह उदाहरण है जहां मैंने चरित्र को हटा दिया है - स्ट्रिंग से।


4
यह बहुत अक्षम है, विशेष रूप से स्वीकृत उत्तर के साथ तुलना में।
एरिक रॉबर्टसन

3
मुझे लगता है कि यह उत्तर काम करता है, लेकिन सही उत्तर यह छोटा और तेज है
badReiko

2

मुझे इस अवसर में RegEx का उपयोग करना पसंद है:

str = str.replace(/X/g, '');

जहाँ g का अर्थ वैश्विक है इसलिए यह आपके पूरे तार से गुजरेगा और सभी X को '' के साथ बदल देगा; यदि आप X और x दोनों को बदलना चाहते हैं, तो आप बस कहते हैं:

str = str.replace(/X|x/g, '');

(मेरी बेला यहां देखें: फिडल )


मुझे लगता है कि यह काम कर सकता है, लेकिन सही जवाब तेजी से और कम क्रियान्वित करता है, यह हमेशा बेहतर है कि RegEx से बचें जितना संभव हो उतना ही अन्य तरीकों की तुलना में धीमी गति से जाना जाता है
badReiko

2

नमस्कार इस कोड को नीचे आज़माएं

public class RemoveCharacter {

    public static void main(String[] args){
        String str = "MXy nameX iXs farXazX";
        char x = 'X';
        System.out.println(removeChr(str,x));
    }

    public static String removeChr(String str, char x){
        StringBuilder strBuilder = new StringBuilder();
        char[] rmString = str.toCharArray();
        for(int i=0; i<rmString.length; i++){
            if(rmString[i] == x){

            } else {
                strBuilder.append(rmString[i]);
            }
        }
        return strBuilder.toString();
    }
}

यदि आप x के बजाय हमारे पास एक और स्ट्रिंग है तो आप यह कैसे करेंगे? अच्छा समाधान!
मोना जलाल

2

रिप्लेस की जगह रिप्लेसमेंट का इस्तेमाल करें

str = str.replaceAll("X,"");

यह आपको वांछित जवाब देना चाहिए।


रिप्लेस की जगह एलील का उपयोग कर समाप्त होता है। कार्यान्वयन में देखो। इस प्रकार स्ट्रिंग # प्रतिस्थापित लागू किया जाता है:return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
Sal_Vader_808

0
package com.acn.demo.action;

public class RemoveCharFromString {

    static String input = "";
    public static void main(String[] args) {
        input = "abadbbeb34erterb";
        char token = 'b';
        removeChar(token);
    }

    private static void removeChar(char token) {
        // TODO Auto-generated method stub
        System.out.println(input);
        for (int i=0;i<input.length();i++) {
            if (input.charAt(i) == token) {
            input = input.replace(input.charAt(i), ' ');
                System.out.println("MATCH FOUND");
            }
            input = input.replaceAll(" ", "");
            System.out.println(input);
        }
    }
}

input = "deletes all blanks too";"विलोपेल्लैंकस्टू" देता है
कपलान

0

यहाँ एक लंबो फ़ंक्शन है जो स्ट्रिंग के रूप में पारित सभी वर्णों को हटा देता है

BiFunction<String,String,String> deleteChars = (fromString, chars) -> {
  StringBuilder buf = new StringBuilder( fromString );
  IntStream.range( 0, buf.length() ).forEach( i -> {
    while( i < buf.length() && chars.indexOf( buf.charAt( i ) ) >= 0 )
      buf.deleteCharAt( i );
  } );
  return( buf.toString() );
};

String str = "TextX XYto modifyZ";
deleteChars.apply( str, "XYZ" ); // –> "Text to modify"

यह समाधान इस बात पर जोर देता है कि जिसके परिणामस्वरूप स्ट्रिंग - अंतर में replace()- वर्णों को हटाते समय शुरू होने वाले स्ट्रिंग से बड़ा कभी नहीं होता है। तो यह बार-बार आवंटन और नकल से बचता है जबकि चरित्र-वार को StringBuilderजैसा replace()करता है वैसा ही करता है।
उस समय की निरर्थक पीढ़ी Patternऔर Matcherउदाहरणों का उल्लेख replace()नहीं करना चाहिए जिन्हें हटाने की आवश्यकता नहीं है। इस समाधान के
अंतर replace()में एक झपट्टा में कई पात्रों को हटा सकते हैं।


लैम्ब्डा / फंक्शनल प्रोग्रामिंग अभी बहुत हिप है, लेकिन इसका उपयोग एक समाधान बनाने के लिए है जो चुने गए उत्तर की तुलना में 10x लंबा है, आईएमएचओ को उचित नहीं ठहराया जा सकता है, इसलिए नीचे वोट।
वोल्क्समैन

str.replace("…", "")झटपट private Pattern(…)और फिर उत्पन्न पैटर्न कॉल पर public String replaceAll(String repl)। तो निम्नलिखित फ़ंक्शन-कॉल हुआ: return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); - Sal_Vader_808 टिप्पणी देखें। सभी सभी ca 3 बार मेरे हिप लैम्ब्डा समाधान की तुलना में लंबे समय तक । और यहाँ यह अच्छी तरह से समझाया गया है कि क्यों मेरी कूल्हे का लैम्ब्डा समाधान भी तेज क्यों है
कपलान

अपनी बात में : यदि यह वास्तव में समाधान के आकार के बारे में था, तो कुछ अन्य समाधान दो बार बड़े या समाधान के लिए बाहरी पुस्तकालय की आवश्यकता होती है जो आलोचना के लिए अधिक उपयुक्त उम्मीदवार होंगे। एक भाषा एक्सटेंशन जो कि 8 साल से भाषा का हिस्सा है क्योंकि जावा 8 वास्तव में हिप नहीं है । स्कोरिंग प्रणाली के साथ एक सामान्य समस्या यह है कि समय कारक एक समाधान की गुणवत्ता से अधिक भारी होता है। नतीजतन, अधिक अप-टू-डेट और कभी-कभी बेहतर समाधान भी तेजी से पीछे के तीसरे में पाए जा रहे हैं।
कापलान

मैं कोड नहीं निष्पादन की गति के संदर्भ में 10x लंबे समय तक का उल्लेख कर रहा था। कुछ भी जो एक रेगेक्स पैटर्न को संकलित करता है जिसे हर बार कहा जाता है वह बहुत धीमा हो सकता है। आपको वास्तव में संकलित मिलानकर्ता को कैश करने की आवश्यकता होगी और यदि उच्च आवृत्ति पर इस तरह के रीजेक्स का उपयोग किया जाता है (ओपी यह नहीं कहता है कि यह किस परिदृश्य में उपयोग किया जाता है - एक फॉर्म सबमिशन से डेटा को साफ करने के लिए एक दुर्लभ परिदृश्य हो सकता है या एक तंग में इस्तेमाल किया जा सकता है। लूप को दूसरी बार के अतिरिक्त कहा जा रहा है)।
वोल्समैन

प्रदर्शन संबंधी चिंताओं के संबंध में, मैंने एक नया उत्तर जोड़ा जो प्रदान किए गए विभिन्न प्रकार के उत्तरों पर एक त्वरित बेंचमार्क चलाता है। यदि ओपी इस ऑपरेशन को बार-बार कर रहा है तो उन्हें String.replace () विकल्प से बचना चाहिए क्योंकि हुड के नीचे रेगेक्स पैटर्न के बार-बार पुन: संयोजन बहुत महंगा है।
21

0

एक प्रदर्शन बेंचमार्क के साथ मुख्य उत्तरों का मूल्यांकन जो उन चिंताओं की पुष्टि करता है कि वर्तमान चुना गया उत्तर हूड के तहत महंगा रेक्सएक्स ऑपरेशन करता है

प्रदान किए गए उत्तर आज तक 3 मुख्य शैलियों (जावास्क्रिप्ट उत्तर को अनदेखा करते हुए;) में आते हैं:

  • String.replace (charsToDelete, "") का उपयोग करें; जो हुड के नीचे रेगेक्स का उपयोग करता है
  • लैम्ब्डा का उपयोग करें
  • सरल जावा कार्यान्वयन का उपयोग करें

कोड आकार के संदर्भ में स्पष्ट रूप से String.replace सबसे अधिक प्रचलित है। सरल जावा कार्यान्वयन लैम्ब्डा की तुलना में थोड़ा छोटा और क्लीनर (IMHO) है (मुझे गलत मत समझो - मैं लैम्बडा का उपयोग अक्सर करता हूं जहां वे उपयुक्त होते हैं)

निष्पादन की गति सबसे तेज़ से धीमी गति से चलने के क्रम में थी: सरल जावा कार्यान्वयन, लैम्ब्डा और फिर स्ट्रिंग (क्रेप) () (जो रेगेक्स को आमंत्रित करता है)।

अब तक सबसे तेज़ कार्यान्वयन सरल जावा कार्यान्वयन ट्यून था ताकि यह अधिकतम संभव परिणाम की लंबाई के लिए स्ट्रिंगब्यूलर बफर का प्रचार करता है और फिर बस बफर को चार्ट जोड़ता है जो "स्ट्रिंग को हटाने के लिए" नहीं हैं। यह स्ट्रिंग्स> 16 वर्णों की लंबाई (स्ट्रिंगब्रुएटर के लिए डिफ़ॉल्ट आवंटन) में होने वाले किसी भी वास्तविक परिवर्तन से बचा जाता है और यह स्ट्रिंग की एक प्रतिलिपि से वर्णों को हटाने के "स्लाइड लेफ्ट" प्रदर्शन हिट से बचाता है जो लैम्बडा कार्यान्वयन है।

नीचे दिया गया कोड एक साधारण बेंचमार्क टेस्ट चलाता है, प्रत्येक कार्यान्वयन को 1,000,000 बार चलाता है और बीता हुआ समय लॉग करता है।

प्रत्येक रन के साथ सटीक परिणाम भिन्न होते हैं लेकिन प्रदर्शन का क्रम कभी नहीं बदलता है:

Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms

लैंबडा कार्यान्वयन (कपलान के जवाब से कॉपी किया गया) धीमा हो सकता है क्योंकि यह सभी पात्रों के "एक के द्वारा छोड़ी गई" विशेषता को हटाता है। यह स्पष्ट रूप से लंबे समय तक तार के साथ खराब हो जाएगा जिसमें बहुत सारे पात्रों को हटाने की आवश्यकता होगी। इसके अलावा लैम्ब्डा कार्यान्वयन में कुछ ओवरहेड हो सकते हैं।

String.replace कार्यान्वयन, regex का उपयोग करता है और प्रत्येक कॉल पर एक regex "संकलन" करता है। इसका एक अनुकूलन रीगेक्स का सीधे उपयोग करना और संकलित पैटर्न को कैश करना होगा ताकि इसे हर बार संकलित करने की लागत से बचा जा सके।

package com.sample;

import java.util.function.BiFunction;
import java.util.stream.IntStream;

public class Main {

    static public String deleteCharsSimple(String fromString, String charsToDelete)
    {
        StringBuilder buf = new StringBuilder(fromString.length()); // Preallocate to max possible result length
        for(int i = 0; i < fromString.length(); i++)
            if (charsToDelete.indexOf(fromString.charAt(i)) < 0)
                buf.append(fromString.charAt(i));   // char not in chars to delete so add it
        return buf.toString();
    }

    static public String deleteCharsLambda(String fromString1, String charsToDelete)
    {
        BiFunction<String, String, String> deleteChars = (fromString, chars) -> {
            StringBuilder buf = new StringBuilder(fromString);
            IntStream.range(0, buf.length()).forEach(i -> {
                while (i < buf.length() && chars.indexOf(buf.charAt(i)) >= 0)
                    buf.deleteCharAt(i);
            });
            return (buf.toString());
        };

        return deleteChars.apply(fromString1, charsToDelete);
    }

    static public String deleteCharsReplace(String fromString, String charsToDelete)
    {
        return fromString.replace(charsToDelete, "");
    }


    public static void main(String[] args)
    {
        String str = "XXXTextX XXto modifyX";
        String charsToDelete = "X";  // Should only be one char as per OP's requirement

        long start, end;

        System.out.println("Start simple");
        start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++)
            deleteCharsSimple(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));

        System.out.println("Start lambda");
        start = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++)
            deleteCharsLambda(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));

        System.out.println("Start replace");
        start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++)
            deleteCharsReplace(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));
    }
}

यदि लैम्ब्डा फ़ंक्शन को कहा जाता है जैसा कि यह करने का इरादा है, समय निम्नलिखित है (कोई भी लैम्बडा फ़ंक्शन को सदस्य फ़ंक्शन में लपेटता है) । इसके अलावा आपका DeleteCharsReplace () गलत तरीके से लागू किया गया है: यह एक स्ट्रिंग "XYZ" की जगह लेता है और 'X', 'Y' और 'Z' fromString.replace("X", "").replace("Y", "").replace("Z", "");की आवश्यकता नहीं होती है। अब हमें सही समय मिल गया है: सरल समय शुरू करें: 759 | लैम्बडा टाइम शुरू करें: 1092 | DeleteCharsLambda () समय शुरू करें: 1420 | : प्रारंभ को सही जगह समय 4636
कापलान

"कोई भी एक लंबो फ़ंक्शन को सदस्य फ़ंक्शन में नहीं लपेटता है" - इसे बेंचमार्क परिदृश्य में कॉल करने के उद्देश्य के अलावा ताकि यह उस तरह से संगत हो जिस तरह से अन्य कार्यान्वयन कहा जाता है।
वोक्समैन 21:19

मुझे बस एहसास हुआ कि ओपी ने एक ही चरित्र की सभी घटनाओं को हटाने के बारे में पूछा, लेकिन आपके जवाब ने पात्रों के एक सेट से निपटने के लिए गुंजाइश बदल दी। "स्वीकृत" उत्तर कार्यान्वयन जो मैंने उपयोग किया था और कई पात्रों के लिए पूरा करने का इरादा नहीं था। इसलिए मैंने इसे और बेंचमार्क समय को दर्शाने के लिए उपरोक्त बेंचमार्क को अपडेट किया है। यदि आप कई बार कॉल करने के लिए कई वर्णों का समर्थन करने के लिए गुंजाइश बढ़ाना चाहते हैं तो BTW महंगा है। एक कॉल करने के लिए स्विच करने के लिए बेहतर है कि सभी को बदलें ("[XYZ]", "")
वोक्समैन

समाधान में दिखाए गए फ़ंक्शन को केवल एक बार कॉल किए जाने के दौरान ही इनलेट किया जाता है। फ़ंक्शन फ़ंक्शन के अतिरिक्त फ़ंक्शन को सदस्य फ़ंक्शन में लपेटने के लिए बेंचमार्क को विकृत करने का एकमात्र प्रभाव है।
कपलान

प्रत्येक कॉल के भिन्नता के रूप में एक ही कॉल करके एक त्वरित कॉल विधि को ठीक से बेंचमार्क करना लगभग असंभव है। इसलिए बेंचमार्किंग में सामान्य रूप से एक ही विधि के लिए कई बार-बार कॉल शामिल होते हैं और फिर कुल समय का मूल्यांकन कुल विकल्पों के साथ तुलना करने के लिए किया जाता है (या यदि आवश्यक हो तो एक औसत की गणना करने के लिए) ..
वोल्क्समैन

0

प्रतिस्थापन के समय आपको वर्णों को वर्ग कोष्ठक के अंदर निकालने की आवश्यकता होगी। उदाहरण कोड निम्नानुसार होगा:

String s = "$116.42".replaceAll("[$]", "");

-3

आप str = str.replace("X", "");पहले बताए अनुसार उपयोग कर सकते हैं और आप ठीक हो जाएंगे। आपकी जानकारी के ''लिए एक खाली (या एक वैध) चरित्र नहीं '\0'है, लेकिन है।

इसलिए आप str = str.replace('X', '\0');इसके बजाय उपयोग कर सकते हैं ।


9
यह गलत है। '\ 0' एक वास्तविक अशक्त चरित्र का निर्माण करेगा। str.replace ('X', '\ 0') str.replace ("X", "\ u0000") के बराबर है, जो ओपी चाहता है वह बिल्कुल नहीं है
एंड्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.