2010-08-12 13 views
61

क्या मुझे कुछ याद आ रहा है, या क्या स्ट्रिंगबिल्डर में एक स्ट्रिंग बी के साथ स्ट्रिंग ए की सभी घटनाओं को प्रतिस्थापित करता है "सामान्य स्ट्रिंग क्लास करता है? स्ट्रिंगबिल्डर फ़ंक्शन को प्रतिस्थापित करना बिल्कुल समान नहीं है। क्या सामान्य स्ट्रिंग क्लास का उपयोग करके कई स्ट्रिंग्स उत्पन्न किए बिना इसे और अधिक कुशलता से कोई रास्ता है?स्ट्रिंगबिल्डर का उपयोग कर स्ट्रिंग की सभी घटनाओं को बदलें?

public static void replaceAll(StringBuilder builder, String from, String to) 
{ 
    int index = builder.indexOf(from); 
    while (index != -1) 
    { 
     builder.replace(index, index + from.length(), to); 
     index += to.length(); // Move to the end of the replacement 
     index = builder.indexOf(from, index); 
    } 
} 

नोट कुछ मामलों में यह lastIndexOf उपयोग करने के लिए, पीछे से काम कर तेजी से हो सकता है कि:

+0

http://download.oracle.com/javase/1.5.0/docs/api/java /lang/StringBuilder.html मुझे नहीं पता कि मुझे कुछ याद आ रहा है, लेकिन वह फ़ंक्शन मौजूद नहीं है। – garsh0p

+0

आपको क्या लगता है कि ऑब्जेक्ट आवंटन इसे करने का एक कम प्रभावी तरीका है? प्रत्येक "इन-प्लेस" प्रतिस्थापन चरण द्वारा कितने पात्रों की प्रतिलिपि बनाने की आवश्यकता है, इस पर निर्भर करता है कि यह इन-प्लेस ऑपरेशन को भी निष्पादित कर सकता है। – Dirk

+1

'String.replaceAll' चीज़ * regexs * के साथ? मैं 'स्ट्रिंगबिल्डर' और 'स्ट्रिंग' के बीच कनवर्ट करने के ऊपरी हिस्से के बारे में चिंता नहीं करता। –

उत्तर

67

ठीक है, आप एक पाश लिख सकते हैं। मुझे संदेह है कि यह मामला है यदि आप एक छोटी स्ट्रिंग को एक छोटे से स्ट्रिंग के साथ बदल रहे हैं - इसलिए जब आप शुरुआत करते हैं, तो किसी भी प्रतिस्थापन की प्रतिलिपि कम होती है। वैसे भी, यह आपको एक प्रारंभिक बिंदु देना चाहिए।

+1

ध्यान दें कि यदि 'से' और' '' की अलग-अलग लंबाई है तो यह समाधान प्रत्येक प्रतिस्थापन पर बफर पूंछ को स्थानांतरित करेगा। यह कई प्रतिस्थापन घटनाओं के साथ लंबे बफर के लिए काफी अप्रभावी हो सकता है। रॉन रोमेरो के जवाब में यह कमी नहीं है लेकिन इसमें एकल regexp खोज शामिल है। मुझे लगता है कि उपयोग मामले पर तेजी से क्या निर्भर करेगा। – Vadzim

2

java.util.regex.Pattern.matcher(CharSequence s) एक तर्क के रूप एक StringBuilder उपयोग कर सकते हैं इसलिए आप आप builder.toString बुला बिना start() और अंत() का उपयोग कर अपने पैटर्न की प्रत्येक क्रिया की जगह ले सकता()

31

आप Pattern/Matcher इस्तेमाल कर सकते हैं। replaceAllकी विधि स्ट्रिंग वर्ग के JavaDoc पर

Pattern p = Pattern.compile("cat"); 
Matcher m = p.matcher("one cat two cats in the yard"); 
StringBuffer sb = new StringBuffer(); 
while (m.find()) { 
    m.appendReplacement(sb, "dog"); 
} 
m.appendTail(sb); 
System.out.println(sb.toString()); 
+0

यह वही है जो मैं खोज रहा था। Tnx! – dierre

+5

यह लगभग Matcher # replaceAll() के समान है। – Shannon

+0

यह "कुत्ते" के लिए काम करता है लेकिन _general_ मामले में अपर्याप्त है क्योंकि प्रतिस्थापन स्ट्रिंग में विशेष वर्ण हैं। यदि आप प्रतिस्थापन मूल्यों में बैक-रेफरेंस का उपयोग करना चाहते हैं, तो आपको सभी _other_ बैकस्लैश और '$' से बचने की आवश्यकता है। यदि आपको मिलान की गई स्ट्रिंग को बिल्कुल संदर्भित करने की आवश्यकता नहीं है, तो आप 'Matcher.quoteReplacement (...)' के माध्यम से प्रतिस्थापन टेक्स्ट चला सकते हैं। तो 'm.appendReplacement (एसबी, Matcher.quoteReplacement (someText));' – AndrewF

11

देखो: Matcher javadocs से

इस स्ट्रिंग है कि दिया प्रतिस्थापन के साथ दिए गए नियमित एक्सप्रेशन से मेल खाने के प्रत्येक स्ट्रिंग से बदलता है। प्रपत्र str.replaceAll की इस पद्धति की एक मंगलाचरण (regex, repl) वास्तव में एक ही परिणाम अभिव्यक्ति

java.util.regex.Pattern.compile (regex) .matcher (एसटीआर) .replaceAll के रूप में पैदावार (repl)

आप देख सकते हैं आपको लगता है कि ऐसा करने के लिए पैटर्न और Matcher उपयोग कर सकते हैं।

2

उपयोग निम्नलिखित:

/** 
* Utility method to replace the string from StringBuilder. 
* @param sb   the StringBuilder object. 
* @param toReplace the String that should be replaced. 
* @param replacement the String that has to be replaced by. 
* 
*/ 
public static void replaceString(StringBuilder sb, 
           String toReplace, 
           String replacement) {  
    int index = -1; 
    while ((index = sb.lastIndexOf(toReplace)) != -1) { 
     sb.replace(index, index + toReplace.length(), replacement); 
    } 
} 
4

यहां तक ​​कि साधारण एक स्ट्रिंग उपयोग कर रहा है ReplaceAll ही कार्य करते हैं। आप इसे

StringBuilder sb = new StringBuilder("Hi there, are you there?") 
System.out.println(Pattern.compile("there").matcher(sb).replaceAll("niru")); 
1

यहां एक जगह बदल दी गई है जो सभी स्ट्रिंगबिल्डर में पारित हो जाएगी। मैंने सोचा कि मैं इसे पोस्ट करूँगा क्योंकि मैं एक नया स्ट्रिंग बनाने के साथ प्रतिस्थापित करना चाहता था।

public static void replaceAll(StringBuilder sb, Pattern pattern, String replacement) { 
    Matcher m = pattern.matcher(sb); 
    while(m.find()) { 
     sb.replace(m.start(), m.end(), replacement); 
    } 
} 

मैं कैसे सरल कोड यह था करने के लिए झटका लगा (किसी कारण मैं StringBuilder बदलते मिलान का उपयोग करते समय समूह प्रारंभ/समाप्ति की फेंक सोचा लेकिन यह नहीं है के लिए)।

यह शायद अन्य रेगेक्स उत्तरों की तुलना में तेज़ है क्योंकि पैटर्न पहले ही संकलित है और आप एक नई स्ट्रिंग नहीं बना रहे हैं, लेकिन मैंने कोई बेंचमार्किंग नहीं की है।

public StrBuilder replaceAll(String searchStr, String replaceStr) 

* यह रेगुलर एक्सप्रेशन लेकिन एक साधारण स्ट्रिंग प्राप्त नहीं होता है:

9

@Adam: मुझे लगता है कि आपके कोड स्निपेट में आपको m.find() के लिए प्रारंभ स्थिति को ट्रैक करना चाहिए क्योंकि अंतिम वर्ण मिलान के बाद स्ट्रिंग प्रतिस्थापन ऑफ़सेट बदल सकता है।

public static void replaceAll(StringBuilder sb, Pattern pattern, String replacement) { 
    Matcher m = pattern.matcher(sb); 
    int start = 0; 
    while (m.find(start)) { 
     sb.replace(m.start(), m.end(), replacement); 
     start = m.start() + replacement.length(); 
    } 
} 
+0

मुझे लगता है कि आप सही हैं। मुझे यह जांचना होगा कि मैं किसके साथ समाप्त हुआ। –

+1

सबसे मेमोरी कुशल कोड। बधाई! –

0
public static String replaceCharsNew(String replaceStr,Map<String,String> replaceStrMap){ 
     StringBuilder replaceStrBuilder = new StringBuilder(replaceStr); 
     Set<String> keys=replaceStrMap.keySet(); 
     for(String invalidChar:keys){ 
      int index = -1; 
      while((index=replaceStrBuilder.indexOf(invalidChar,index)) !=-1){ 
       replaceStrBuilder.replace(index,index+invalidChar.length(),replaceStrMap.get(invalidChar)); 
      } 
     } 
     return replaceStrBuilder.toString(); 
    } 
+0

आपको वास्तव में कुछ स्पष्टीकरण जोड़ना चाहिए कि इस कोड को क्यों काम करना चाहिए - आप कोड में टिप्पणियां भी जोड़ सकते हैं - अपने वर्तमान रूप में, यह कोई स्पष्टीकरण प्रदान नहीं करता है जो समुदाय के बाकी हिस्सों को समझने में मदद कर सकता है कि आपने क्या किया प्रश्न हल/उत्तर दें। – ishmaelMakitla

+0

मेरे पास यह निम्नलिखित परिदृश्य था कि मुझे कुछ वर्णों के साथ कई अमान्य वर्णों को प्रतिस्थापित करने की आवश्यकता है। मैं तो बस ऊपर दिए गए कोड का छोटा सा बदलाव किया और पोस्ट करने के लिए करना चाहता था यह @JUnitTest सार्वजनिक शून्य testReplaceCharsNew() { \t नक्शा <स्ट्रिंग, स्ट्रिंग> नक्शा = नए HashMap <स्ट्रिंग, स्ट्रिंग>(); \t map.put (",", "/"); \t map.put ("।", ""); \t map.put (";", "/"); \t स्ट्रिंग एस = Utils.replaceCharsNew ("परीक्षण; बदलें, वर्ण, नया।", मानचित्र); \t assertEquals ("परीक्षण/प्रतिस्थापन/वर्ण/नया", एस); } – ramesh

1

के बारे में विधि बना सकते हैं और String.replaceAll यह तुम्हारे लिए क्या करते हैं कैसे:

public static void replaceAll(StringBuilder sb, String regex, String replacement) 
{ 
    String aux = sb.toString(); 
    aux = aux.replaceAll(regex, replacement); 
    sb.setLength(0); 
    sb.append(aux);  
} 
संबंधित मुद्दे