2011-09-23 11 views
5

overlaps आप निम्नलिखित स्ट्रिंग है कहते हैं:जावा में एक से अधिक सबस्ट्रिंग की जगह जब प्रतिस्थापन पाठ खोज पाठ

cat dog fish dog fish cat 

आप dogs के साथ सभी cats, fish के साथ सभी dogs, और cats के साथ सभी fish बदलना चाहते हैं। Intuitively, अपेक्षित परिणाम:

dog fish cat fish cat dog 

आप स्पष्ट समाधान की कोशिश करते हैं, तो replaceAll() साथ के माध्यम से पाशन, आपको मिलता है:

  1. (मूल) cat dog fish dog fish cat
  2. (बिल्ली -> कुत्ता) dog dog fish dog fish dog
  3. (कुत्ता -> मछली) fish fish fish fish fish fish
  4. (मछली -> बिल्ली) cat cat cat cat cat cat

स्पष्ट रूप से, यह इच्छित परिणाम नहीं है। तो ऐसा करने का सबसे आसान तरीका क्या है? मैं Pattern और Matcher (और Pattern.quote() और Matcher.quoteReplacement()) के साथ कुछ एक साथ जोड़ सकता हूं, लेकिन मुझे विश्वास है कि मैं इस समस्या के लिए पहला व्यक्ति हूं और इसे हल करने के लिए कोई लाइब्रेरी फ़ंक्शन नहीं है।

(Fwiw, वास्तविक मामले में थोड़ा और अधिक जटिल है और सीधे स्वैप शामिल नहीं है।)

उत्तर

8

ऐसा लगता है Apache Commons में StringUtils.replaceEach आप क्या चाहते हैं करता है:

StringUtils.replaceEach("abcdeab", new String[]{"ab", "cd"}, new String[]{"cd", "ab"}); 
// returns "cdabecd" 

ध्यान दें कि ऊपर दिए गए लिंक पर documenent त्रुटि में हो रहा है। विवरण के लिए नीचे टिप्पणियां देखें।

+0

कम से कम स्ट्रिंगयूट्स 2.5 और इससे पहले में स्पष्ट रूप से वर्जित किया गया है: "फेंकता है: अवैध अर्ग्यूमेंट अपवाद - यदि खोज दोहराई जा रही है और किसी के इनपुट के आउटपुट के कारण अंतहीन पाश है"। (हालांकि मुझे वास्तव में जो मिलता है वह एक अवैध स्टाइल अपवाद है क्योंकि रिकर्सन ठीक से रुकने में विफल रहता है।) –

+0

मैं उलझन में हूं। जिस विधि को मैंने ऊपर उद्धृत किया है (जिसे मैंने सीधे ऑनलाइन जावाडॉक्स से कॉपी किया है) भी बाहर नहीं निकलता है। अंतिम बुलियन पैरामीटर के साथ कोई प्रतिस्थापन नहीं है। दूसरी ओर 'StringUtils.replaceEach ("abcde", नया स्ट्रिंग [] {"ab", "cd"}, नया स्ट्रिंग [] {"cd", "ab"})' रिटर्न '"cdabe" 'जो लगता है सही होना। मैंने इसे 2.5 –

+0

पर ठीक किया, कुछ स्पष्टता। 'eERepeatedly' को बदलें 'IllegalStateException' जैसे आपने लिखा था। पिछले 'बूलियन' पैरामीटर के साथ 'प्रतिस्थापित करें' मौजूद नहीं है। पिछले 'बूलियन 'पैरामीटर के बिना' replaceEach' 'नौकरी करना प्रतीत होता है। –

4

मैं एक StringBuilder बनाने और उसके बाद एक समय में पाठ एक बार, एक शब्द पार्स होगा, अपरिवर्तित शब्दों या बदले गए शब्दों पर स्थानांतरित करते हुए मैं जाता हूं। जैसा कि आप सुझाव दे रहे हैं, मैं प्रत्येक स्वैप के लिए इसे पार्स नहीं करूँगा।

तो की तरह कुछ कर के बजाय:

// pseudocode 
text is new text swapping cat with dog 
text is new text swapping dog with fish 
text is new text swapping fish with cat 

मैं

for each word in text 
    if word is cat, swap with dog 
    if word is dog, swap with fish 
    if word is fish, swap with cat 
    transfer new word (or unchanged word) into StringBuilder. 

मैं शायद इस के लिए एक स्वैप (...) विधि बनाने चाहते हैं करते हैं और के लिए एक HashMap का उपयोग करेंगे स्वैप।

उदाहरण

लिए

import java.util.HashMap; 
import java.util.Map; 
import java.util.Scanner; 

public class SwapWords { 
    private static Map<String, String> myMap = new HashMap<String, String>(); 

    public static void main(String[] args) { 
     // this would really be loaded using a file such as a text file or xml 
     // or even a database: 
     myMap.put("cat", "dog"); 
     myMap.put("dog", "fish"); 
     myMap.put("fish", "dog"); 

     String testString = "cat dog fish dog fish cat"; 

     StringBuilder sb = new StringBuilder(); 
     Scanner testScanner = new Scanner(testString); 
     while (testScanner.hasNext()) { 
     String text = testScanner.next(); 
     text = myMap.get(text) == null ? text : myMap.get(text); 
     sb.append(text + " "); 
     } 

     System.out.println(sb.toString().trim()); 
    } 
} 
7
String rep = str.replace("cat","§1§").replace("dog","§2§") 
       .replace("fish","§3§").replace("§1§","dog") 
       .replace("§2§","fish").replace("§3§","cat"); 

बदसूरत और नरक के रूप में अक्षम है, लेकिन काम करता है।


ठीक है, यहां एक और विस्तृत और सामान्य संस्करण है। मैं स्कैनर की बजाय नियमित अभिव्यक्ति का उपयोग करना पसंद करता हूं। इस तरह मैं मनमानी स्ट्रिंग्स को प्रतिस्थापित कर सकता हूं, केवल शब्दों (जो बेहतर या बदतर हो सकता है)।वैसे भी, यहाँ जाता है:

public static String replace(
    final String input, final Map<String, String> replacements) { 

    if (input == null || "".equals(input) || replacements == null 
     || replacements.isEmpty()) { 
     return input; 
    } 
    StringBuilder regexBuilder = new StringBuilder(); 
    Iterator<String> it = replacements.keySet().iterator(); 
    regexBuilder.append(Pattern.quote(it.next())); 
    while (it.hasNext()) { 
     regexBuilder.append('|').append(Pattern.quote(it.next())); 
    } 
    Matcher matcher = Pattern.compile(regexBuilder.toString()).matcher(input); 
    StringBuffer out = new StringBuffer(input.length() + (input.length()/10)); 
    while (matcher.find()) { 
     matcher.appendReplacement(out, replacements.get(matcher.group())); 
    } 
    matcher.appendTail(out); 
    return out.toString(); 
} 

टेस्ट कोड:

System.out.println(replace("cat dog fish dog fish cat", 
    ImmutableMap.of("cat", "dog", "dog", "fish", "fish", "cat"))); 

आउटपुट:

कुत्ता मछली बिल्ली मछली बिल्ली कुत्ता

जाहिर है इस समाधान केवल भावना में कई के लिए बनाता है प्रतिस्थापन, अन्यथा यह एक विशाल ओवरकिल है।

+0

+1 अच्छा, मैं इसे –

+0

@ Eng.Fouad यह संभव नहीं है इस तरह के एक बदसूरत abomination :-) –

+0

मुझे पसंद चाहते चाहते अस्थायी शब्दों वाले शब्दों को प्रतिस्थापित करने का विचार –

0
public class myreplase { 
    public Map<String, String> replase; 

    public myreplase() { 
     replase = new HashMap<String, String>(); 

     replase.put("a", "Apple"); 
     replase.put("b", "Banana"); 
     replase.put("c", "Cantalope"); 
     replase.put("d", "Date"); 
     String word = "a b c d a b c d"; 

     String ss = ""; 
     Iterator<String> i = replase.keySet().iterator(); 
     while (i.hasNext()) { 
      ss += i.next(); 
      if (i.hasNext()) { 
       ss += "|"; 
      } 
     } 

     Pattern pattern = Pattern.compile(ss); 
     StringBuilder buffer = new StringBuilder(); 
     for (int j = 0, k = 1; j < word.length(); j++,k++) { 
      String s = word.substring(j, k); 
      Matcher matcher = pattern.matcher(s); 
      if (matcher.find()) { 
       buffer.append(replase.get(s)); 
      } else { 
       buffer.append(s); 
      } 
     } 
     System.out.println(buffer.toString()); 
    } 

    public static void main(String[] args) { 
     new myreplase(); 
    } 
} 

आउटपुट: - एप्पल केले ख़रबूज़ा दिनांक एप्पल केले ख़रबूज़ा दिनांक

संबंधित मुद्दे