मैं दो तारों को इस तरह से कैसे बदल सकता हूं कि एक दूसरे को बदलने की जगह खत्म न हो?


162

मान लीजिए कि मेरे पास निम्नलिखित कोड हैं:

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar."
story = story.replace("foo", word1);
story = story.replace("bar", word2);

इस कोड के चलने के बाद, का मान storyहोगा"Once upon a time, there was a foo and a foo."

एक समान समस्या तब होती है यदि मैंने उन्हें विपरीत क्रम में प्रतिस्थापित किया है:

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar."
story = story.replace("bar", word2);
story = story.replace("foo", word1);

का मान storyहोगा"Once upon a time, there was a bar and a bar."

मेरा लक्ष्य चालू करने के लिए है storyमें "Once upon a time, there was a bar and a foo."मैं ऐसा कैसे हासिल कर सकता है?


7
+1 वहाँ निश्चित रूप से कुछ समारोह होना चाहिए swap(String s1, String s2, String s3)कि अदला-बदली की सभी घटनाओं s2के साथ s3, और इसके विपरीत।
रयान

क्या हम मान सकते हैं कि इनपुट में प्रत्येक स्वेत शब्द की केवल एक घटना है?
आईसीज़ा

14
कॉर्नर-केस: "अबाबेबाबा" में "अब" और "बा" की अदला-बदली करने पर हम आउटपुट के रूप में क्या उम्मीद करते हैं?
हेगन वॉन एटिज़ेन

1
आपके पास नीचे कुछ अच्छे समाधान हैं, लेकिन क्या आप समझते हैं कि आपका दृष्टिकोण काम क्यों नहीं करता है? सबसे पहले, आपके पास "एक फू और एक बार था"। पहली जगह ("फू" -> "बार") के बाद आपके पास "एक बार और एक बार" था। अब आपके पास "बार" की 2 घटनाएं हैं, इसलिए आपका दूसरा प्रतिस्थापन वह नहीं करता है जो आप अपेक्षा करते हैं - इसका कोई तरीका नहीं है कि आप केवल उस व्यक्ति को प्रतिस्थापित करना चाहते हैं जिसे आपने पिछली बार पहले से बदला नहीं था। @HagenvonEitzen दिलचस्प। मैं एक कार्यशील समाधान की अपेक्षा करता हूं कि वह पहले से मिल रहे स्ट्रिंग को मिलाने और बदलने की जगह ले और फिर बदले हुए खंड के अंत में दोहराए।
DeveloperInDevelopment

1
Jeroen का समाधान वह है जिसे मैं अक्सर पाठ संपादकों में उपयोग करता हूं, जब मुझे बल्क का नाम बदलने की आवश्यकता होती है। यह सरल है, समझने में आसान है, इसके लिए किसी विशेष पुस्तकालय की आवश्यकता नहीं है, और विचार के एक अंश के साथ मूर्खतापूर्ण हो सकता है।
हॉट लिक्स

जवाबों:


88

Apache Commons StringUtilsreplaceEach() से विधि का उपयोग करें :

StringUtils.replaceEach(story, new String[]{"foo", "bar"}, new String[]{"bar", "foo"})

2
किसी भी विचार वास्तव में क्या आंतरिक रूप से प्रतिस्थापित करता है?
मारेक

3
@Marek यह बहुत संभावना है कि फ़ंक्शन प्रत्येक आइटम को खोज और अनुक्रमित करता है, फिर सभी को अनुक्रमित करने के बाद उन सभी को बदल देता है।

16
आप इसके लिए स्रोत यहां लाइन 4684 के आसपास पा सकते हैं ।
जीरो वेनवेल

यह अफ़सोस की बात है कि जब nullइसे पारित किया जाता है तो यह एक नो-ऑप होता है।
11

87

आप एक मध्यवर्ती मान का उपयोग करते हैं (जो वाक्य में अभी तक मौजूद नहीं है)।

story = story.replace("foo", "lala");
story = story.replace("bar", "foo");
story = story.replace("lala", "bar");

आलोचना के लिए एक प्रतिक्रिया के रूप में: आप की तरह एक बड़ा पर्याप्त असामान्य स्ट्रिंग का उपयोग करता है, तो zq515sqdqs5d5sq1dqs4d1q5dqqé "और é5d4sqjshsjddjhodfqsqc, nvùq ^ μù; घ & € SDQ: डी:;) àçàçlala और उपयोग कि, यह बिंदु है जहां मैं भी यह बहस नहीं होगा की संभावना नहीं है एक उपयोगकर्ता कभी भी इसे दर्ज करेगा। यह जानने का एकमात्र तरीका है कि कोई उपयोगकर्ता स्रोत कोड को जानकर है या नहीं और उस बिंदु पर आप अन्य सभी स्तरों की चिंताओं के साथ हैं।

हां, शायद फैंसी रेगेक्स तरीके हैं। मैं कुछ पठनीय पसंद करता हूं जो मुझे पता है कि मुझ पर भी नहीं टूटेगा।

साथ ही टिप्पणियों में @ दाविद कॉनराड द्वारा दी गई उत्कृष्ट सलाह को दोहराया :

कुछ तार का उपयोग चतुराई से (बेवकूफी से) न होने के लिए चुना। यूनिकोड निजी उपयोग क्षेत्र, U + E000..U + F8FF के पात्रों का उपयोग करें। ऐसे किसी भी वर्ण को पहले निकालें, क्योंकि वे वैध रूप से इनपुट में नहीं होना चाहिए (उनका केवल कुछ एप्लिकेशन के भीतर अनुप्रयोग-विशिष्ट अर्थ है), फिर उन्हें प्रतिस्थापित करते समय प्लेसहोल्डर के रूप में उपयोग करें।


4
@ वर्षाजी मेरा अनुमान है कि "बेहतर" की आपकी परिभाषा पर निर्भर करता है ... अगर यह काम करता है और स्वीकार करने योग्य है, तो अगले प्रोग्रामिंग कार्य के लिए आगे बढ़ें और बाद में इसे सुधारने के दौरान इसे सुधारना मेरा दृष्टिकोण होगा।
मैट कोब्रोव

24
जाहिर है "लाला" केवल एक उदाहरण है। उत्पादन में, आपको " zq515sqdqs5d5sq1dqs4d1q5dqqé" & é & € sdq: d:; àçàçlala "का उपयोग करना चाहिए ।
Jeroen Vannevel

81
कुछ तार का उपयोग चतुराई से (बेवकूफी से) न होने के लिए चुना। यूनिकोड निजी उपयोग क्षेत्र, U + E000..U + F8FF के पात्रों का उपयोग करें। ऐसे किसी भी वर्ण को पहले निकालें, क्योंकि वे वैध रूप से इनपुट में नहीं होना चाहिए (उनका केवल कुछ एप्लिकेशन के भीतर अनुप्रयोग-विशिष्ट अर्थ है), फिर उन्हें प्रतिस्थापित करते समय प्लेसहोल्डर के रूप में उपयोग करें।
डेविड कॉनराड

22
दरअसल, इस पर यूनिकोड एफएक्यू पढ़ने के बाद , मुझे लगता है कि यू + एफडीडी0..यू + एफडीईएफ की सीमा में गैर-शेयरधारक और भी बेहतर विकल्प होंगे।
डेविड कॉनराड

6
@Tayryr ज़रूर, लेकिन किसी को इनपुट को सही करना है, है ना? मुझे उम्मीद है कि एक स्ट्रिंग-रिप्लेसमेंट फंक्शन सभी स्ट्रिंग्स पर काम करता है, लेकिन यह फंक्शन असुरक्षित इनपुट्स के लिए टूट जाता है।
नवीं

33

आप का उपयोग कर कुछ इस तरह की कोशिश कर सकते हैं, Matcher#appendReplacementऔर Matcher#appendTail:

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar.";

Pattern p = Pattern.compile("foo|bar");
Matcher m = p.matcher(story);
StringBuffer sb = new StringBuffer();
while (m.find()) {
    /* do the swap... */
    switch (m.group()) {
    case "foo":
        m.appendReplacement(sb, word1);
        break;
    case "bar":
        m.appendReplacement(sb, word2);
        break;
    default:
        /* error */
        break;
    }
}
m.appendTail(sb);

System.out.println(sb.toString());
एक बार की बात है, एक बार और एक फू था।

2
क्या यह काम करता है अगर foo, barऔर storyसभी के पास अज्ञात मूल्य हैं?
स्टीफन पी

1
@StephenP मैं अनिवार्य रूप से हार्ड-कोडेड "foo"और "bar"रिप्लेसमेंट स्ट्रिंग्स के रूप में ओपी के पास अपने कोड में था, लेकिन एक ही प्रकार का दृष्टिकोण ठीक काम करेगा भले ही उन मूल्यों का पता न हो (आपको इसके भीतर if/ else ifबजाय उपयोग करना होगा -loop)। switchwhile
अर्शजी

6
आप regex बनाने में सावधान रहना होगा। Pattern.quoteकाम, या में आते हैं \Qऔर \E
डेविड कॉनराड

1
@ वर्षाजी - हाँ, ने इसे एक "स्वप्थेस" विधि के रूप में साबित कर दिया, जो वर्ड 1, वर्ड 2 और कहानी को मापदंडों के रूप में ले रहा है। +1
स्टीफन पी

4
यहां तक ​​कि क्लीनर को पैटर्न का उपयोग करना होगा (foo)|(bar)और फिर m.group(1) != nullसे मिलान करने के लिए शब्दों को दोहराने से बचने के लिए जांच करनी चाहिए।
होर्नस्टमन

32

यह एक आसान समस्या नहीं है। और आपके पास जितने अधिक सर्च-रिप्लेसमेंट पैरामीटर हैं, उतने ही पेचीदा। आपके पास कई विकल्प हैं, बदसूरत-सुरुचिपूर्ण, कुशल-बेकार के पैलेट पर बिखरे हुए हैं:

  • StringUtils.replaceEachअपाचे कॉमन्स से @AlanHay अनुशंसित के रूप में उपयोग करें । यदि आप अपनी परियोजना में नई निर्भरता जोड़ने के लिए स्वतंत्र हैं तो यह एक अच्छा विकल्प है। आप भाग्यशाली हो सकते हैं: निर्भरता आपके प्रोजेक्ट में पहले से ही शामिल हो सकती है

  • @Jeroen द्वारा सुझाए गए अनुसार एक अस्थायी प्लेसहोल्डर का उपयोग करें , और 2 चरणों में प्रतिस्थापन करें:

    1. मूल पाठ में मौजूद किसी अनन्य टैग के साथ सभी खोज पैटर्न बदलें
    2. प्लेसहोल्डर्स को वास्तविक लक्ष्य प्रतिस्थापन के साथ बदलें

    यह कई कारणों से एक महान दृष्टिकोण नहीं है: यह सुनिश्चित करने की आवश्यकता है कि पहले चरण में उपयोग किए गए टैग वास्तव में अद्वितीय हैं; यह वास्तव में आवश्यक से अधिक स्ट्रिंग प्रतिस्थापन संचालन करता है

  • सभी पैटर्न से एक regex बनाएँ Matcherऔर StringBuffer@arshajii द्वारा सुझाई गई विधि का उपयोग करें । यह भयानक नहीं है, लेकिन यह भी महान नहीं है, क्योंकि रेगेक्स का निर्माण हैकिश की तरह है, और इसमें वह शामिल है StringBufferजो कुछ समय पहले फैशन से बाहर हो गया था StringBuilder

  • मिलान पैटर्न पर स्ट्रिंग को विभाजित करके, और शेष खंडों पर पुनरावृत्ति करके @mjolka द्वारा प्रस्तावित पुनरावर्ती समाधान का उपयोग करें । यह एक अच्छा समाधान है, कॉम्पैक्ट और काफी सुरुचिपूर्ण है। इसकी कमजोरी संभावित रूप से कई प्रतिस्थापन और संघनन संचालन है, और स्टैक आकार सीमाएं जो सभी पुनरावर्ती समाधानों पर लागू होती हैं

  • शब्दों को पाठ को विभाजित करें और जावा 8 धाराओं का उपयोग करने के लिए प्रतिस्थापनों को सुरुचिपूर्ण ढंग से करने के लिए @msandiford के रूप में सुझाव दिया, लेकिन निश्चित रूप से केवल तभी काम करता है जब आप शब्द सीमाओं में विभाजन के साथ ठीक हों, जो इसे सामान्य समाधान के रूप में उपयुक्त नहीं बनाता है

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

public static String replaceEach(String text, String[] searchList, String[] replacementList) {
    // TODO: throw new IllegalArgumentException() if any param doesn't make sense
    //validateParams(text, searchList, replacementList);

    SearchTracker tracker = new SearchTracker(text, searchList, replacementList);
    if (!tracker.hasNextMatch(0)) {
        return text;
    }

    StringBuilder buf = new StringBuilder(text.length() * 2);
    int start = 0;

    do {
        SearchTracker.MatchInfo matchInfo = tracker.matchInfo;
        int textIndex = matchInfo.textIndex;
        String pattern = matchInfo.pattern;
        String replacement = matchInfo.replacement;

        buf.append(text.substring(start, textIndex));
        buf.append(replacement);

        start = textIndex + pattern.length();
    } while (tracker.hasNextMatch(start));

    return buf.append(text.substring(start)).toString();
}

private static class SearchTracker {

    private final String text;

    private final Map<String, String> patternToReplacement = new HashMap<>();
    private final Set<String> pendingPatterns = new HashSet<>();

    private MatchInfo matchInfo = null;

    private static class MatchInfo {
        private final String pattern;
        private final String replacement;
        private final int textIndex;

        private MatchInfo(String pattern, String replacement, int textIndex) {
            this.pattern = pattern;
            this.replacement = replacement;
            this.textIndex = textIndex;
        }
    }

    private SearchTracker(String text, String[] searchList, String[] replacementList) {
        this.text = text;
        for (int i = 0; i < searchList.length; ++i) {
            String pattern = searchList[i];
            patternToReplacement.put(pattern, replacementList[i]);
            pendingPatterns.add(pattern);
        }
    }

    boolean hasNextMatch(int start) {
        int textIndex = -1;
        String nextPattern = null;

        for (String pattern : new ArrayList<>(pendingPatterns)) {
            int matchIndex = text.indexOf(pattern, start);
            if (matchIndex == -1) {
                pendingPatterns.remove(pattern);
            } else {
                if (textIndex == -1 || matchIndex < textIndex) {
                    textIndex = matchIndex;
                    nextPattern = pattern;
                }
            }
        }

        if (nextPattern != null) {
            matchInfo = new MatchInfo(nextPattern, patternToReplacement.get(nextPattern), textIndex);
            return true;
        }
        return false;
    }
}

इकाई परीक्षण:

@Test
public void testSingleExact() {
    assertEquals("bar", StringUtils.replaceEach("foo", new String[]{"foo"}, new String[]{"bar"}));
}

@Test
public void testReplaceTwice() {
    assertEquals("barbar", StringUtils.replaceEach("foofoo", new String[]{"foo"}, new String[]{"bar"}));
}

@Test
public void testReplaceTwoPatterns() {
    assertEquals("barbaz", StringUtils.replaceEach("foobar",
            new String[]{"foo", "bar"},
            new String[]{"bar", "baz"}));
}

@Test
public void testReplaceNone() {
    assertEquals("foofoo", StringUtils.replaceEach("foofoo", new String[]{"x"}, new String[]{"bar"}));
}

@Test
public void testStory() {
    assertEquals("Once upon a foo, there was a bar and a baz, and another bar and a cat.",
            StringUtils.replaceEach("Once upon a baz, there was a foo and a bar, and another foo and a cat.",
                    new String[]{"foo", "bar", "baz"},
                    new String[]{"bar", "baz", "foo"})
    );
}

21

पहले शब्द को बदलने के लिए खोजें। यदि यह स्ट्रिंग में है, तो घटना के पहले स्ट्रिंग के हिस्से पर, और घटना के बाद स्ट्रिंग के हिस्से पर पुनरावृत्ति करें।

अन्यथा, प्रतिस्थापित किए जाने वाले अगले शब्द के साथ जारी रखें।

एक भोली कार्यान्वयन इस तरह लग सकता है

public static String replaceAll(String input, String[] search, String[] replace) {
  return replaceAll(input, search, replace, 0);
}

private static String replaceAll(String input, String[] search, String[] replace, int i) {
  if (i == search.length) {
    return input;
  }
  int j = input.indexOf(search[i]);
  if (j == -1) {
    return replaceAll(input, search, replace, i + 1);
  }
  return replaceAll(input.substring(0, j), search, replace, i + 1) +
         replace[i] +
         replaceAll(input.substring(j + search[i].length()), search, replace, i);
}

नमूना उपयोग:

String input = "Once upon a baz, there was a foo and a bar.";
String[] search = new String[] { "foo", "bar", "baz" };
String[] replace = new String[] { "bar", "baz", "foo" };
System.out.println(replaceAll(input, search, replace));

आउटपुट:

Once upon a foo, there was a bar and a baz.

एक कम-भोला संस्करण:

public static String replaceAll(String input, String[] search, String[] replace) {
  StringBuilder sb = new StringBuilder();
  replaceAll(sb, input, 0, input.length(), search, replace, 0);
  return sb.toString();
}

private static void replaceAll(StringBuilder sb, String input, int start, int end, String[] search, String[] replace, int i) {
  while (i < search.length && start < end) {
    int j = indexOf(input, search[i], start, end);
    if (j == -1) {
      i++;
    } else {
      replaceAll(sb, input, start, j, search, replace, i + 1);
      sb.append(replace[i]);
      start = j + search[i].length();
    }
  }
  sb.append(input, start, end);
}

दुर्भाग्य से, जावा की Stringकोई indexOf(String str, int fromIndex, int toIndex)विधि नहीं है। मैंने indexOfयहाँ के कार्यान्वयन को छोड़ दिया है क्योंकि मुझे यह निश्चित नहीं है कि यह सही है, लेकिन यह इदोन पर पाया जा सकता है , साथ ही यहाँ पोस्ट किए गए विभिन्न समाधानों के कुछ मोटे समय के साथ।


2
यद्यपि इस तरह की चीजों के लिए अपाचे कॉमन जैसी मौजूदा लाइब्रेरी का उपयोग करना निस्संदेह इस काफी सामान्य समस्या को हल करने का सबसे आसान तरीका है, आपने एक कार्यान्वयन दिखाया है जो शब्दों के हिस्सों पर काम करता है, रनटाइम में तय किए गए शब्दों पर और बिना जादू टोकेन के साथ सब्सट्रिंग को प्रतिस्थापित किए बिना। (वर्तमान में) उच्च मतदान जवाब। +1
बुहब

सुंदर, लेकिन जमीन से टकराता है जब 100 एमबी की इनपुट फ़ाइल की आपूर्ति की जाती है।
क्रिस्टोफ डी ट्रॉयर

12

जावा 8 में वन-लाइनर:

    story = Pattern
        .compile(String.format("(?<=%1$s)|(?=%1$s)", "foo|bar"))
        .splitAsStream(story)
        .map(w -> ImmutableMap.of("bar", "foo", "foo", "bar").getOrDefault(w, w))
        .collect(Collectors.joining());
  • लुकअराउंड रेगुलर एक्सप्रेशन ( ?<=, ?=): http : //www. अनियमित-expressions.info/lookaround.html
  • यदि शब्दों में विशेष रेगेक्स वर्ण हो सकते हैं, तो उनसे बचने के लिए Pattern.quote का उपयोग करें।
  • मैं कंसीव करने के लिए अमरुद इम्यूटेबल मैप का इस्तेमाल करता हूं, लेकिन जाहिर है कि कोई भी मैप काम भी करेगा।

11

यहाँ एक जावा 8 स्ट्रीम संभावना है जो कुछ के लिए दिलचस्प हो सकती है:

String word1 = "bar";
String word2 = "foo";

String story = "Once upon a time, there was a foo and a bar.";

// Map is from untranslated word to translated word
Map<String, String> wordMap = new HashMap<>();
wordMap.put(word1, word2);
wordMap.put(word2, word1);

// Split on word boundaries so we retain whitespace.
String translated = Arrays.stream(story.split("\\b"))
    .map(w -> wordMap.getOrDefault(w,  w))
    .collect(Collectors.joining());

System.out.println(translated);

यहाँ जावा 7 में समान एल्गोरिथ्म का एक सन्निकटन है:

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar.";

// Map is from untranslated word to translated word
Map<String, String> wordMap = new HashMap<>();
wordMap.put(word1, word2);
wordMap.put(word2, word1);

// Split on word boundaries so we retain whitespace.
StringBuilder translated = new StringBuilder();
for (String w : story.split("\\b"))
{
  String tw = wordMap.get(w);
  translated.append(tw != null ? tw : w);
}

System.out.println(translated);

10
यह एक अच्छा सुझाव है जब आपके द्वारा प्रतिस्थापित किया गया सामान रिक्त स्थान (या समान) द्वारा अलग किए गए वास्तविक शब्द हैं , लेकिन यह किसी शब्द के सबस्ट्रिंग को बदलने के लिए काम नहीं करेगा।
साइमन फोर्सबर्ग

Java8 स्ट्रीम के लिए +1। बहुत बुरा यह एक सीमांकक की आवश्यकता है।
नवीं

6

यदि आप एक वाक्य में शब्दों को बदलना चाहते हैं जो सफेद स्थान द्वारा अलग किए गए हैं जैसा कि आपके उदाहरण में दिखाया गया है तो आप इस सरल एल्गोरिथ्म का उपयोग कर सकते हैं।

  1. सफेद स्थान पर विभाजित कहानी
  2. प्रत्येक तत्वों को बदलें, अगर फू इसे बार और वाइस वर्सा में बदल देता है
  3. सरणी को वापस एक स्ट्रिंग में शामिल करें

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

  1. फू शब्द पर विभाजित
  2. सरणी के प्रत्येक तत्व को फू से बदलें
  3. अंतिम को छोड़कर प्रत्येक तत्व के बाद बार जोड़कर उस सरणी में शामिल हों

1
यही मैं सुझाव देने के लिए सोच रहा था। हालांकि यह एक प्रतिबंध जोड़ता है कि पाठ रिक्त स्थान से घिरा हुआ शब्द है। :)
डेवलपर मारियस ėilėnas 11

@ Marius algorithmil Marnas मैंने एक वैकल्पिक एल्गोरिथ्म जोड़ा है।
फास्टकोडजवा

5

यहां मानचित्र का उपयोग करके कम जटिल उत्तर दिया गया है।

private static String replaceEach(String str,Map<String, String> map) {

         Object[] keys = map.keySet().toArray();
         for(int x = 0 ; x < keys.length ; x ++ ) {
             str = str.replace((String) keys[x],"%"+x);
         }

         for(int x = 0 ; x < keys.length ; x ++) {
             str = str.replace("%"+x,map.get(keys[x]));
         }
         return str;
     }

और विधि कहलाती है

Map<String, String> replaceStr = new HashMap<>();
replaceStr.put("Raffy","awesome");
replaceStr.put("awesome","Raffy");
String replaced = replaceEach("Raffy is awesome, awesome awesome is Raffy Raffy", replaceStr);

आउटपुट है: कमाल है रैफी, रैफी रैफी कमाल की है


1
इसके replaced.replaceAll("Raffy", "Barney");बाद चलने से यह सुपाच्य हो जाएगा ... इसके लिए प्रतीक्षा करें; Dary !!!
केएल

3

यदि आप बदलने के लिए खोज स्ट्रिंग के कई आवृत्तियों को संभालने में सक्षम होना चाहते हैं, तो आप प्रत्येक खोज शब्द पर स्ट्रिंग को विभाजित करके आसानी से कर सकते हैं, फिर उसे प्रतिस्थापित कर सकते हैं। यहाँ एक उदाहरण है:

String regex = word1 + "|" + word2;
String[] values = Pattern.compile(regex).split(story);

String result;
foreach subStr in values
{
   subStr = subStr.replace(word1, word2);
   subStr = subStr.replace(word2, word1);
   result += subStr;
}

3

आप निम्न कोड ब्लॉक के साथ अपना लक्ष्य पूरा कर सकते हैं:

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, in a foo, there was a foo and a bar.";
story = String.format(story.replace(word1, "%1$s").replace(word2, "%2$s"),
    word2, word1);

यह आदेश की परवाह किए बिना शब्दों को बदल देता है। आप इस सिद्धांत को एक उपयोगिता विधि में विस्तारित कर सकते हैं, जैसे:

private static String replace(String source, String[] targets, String[] replacements) throws IllegalArgumentException {
    if (source == null) {
        throw new IllegalArgumentException("The parameter \"source\" cannot be null.");
    }

    if (targets == null || replacements == null) {
        throw new IllegalArgumentException("Neither parameters \"targets\" or \"replacements\" can be null.");
    }

    if (targets.length == 0 || targets.length != replacements.length) {
        throw new IllegalArgumentException("The parameters \"targets\" and \"replacements\" must have at least one item and have the same length.");
    }

    String outputMask = source;
    for (int i = 0; i < targets.length; i++) {
        outputMask = outputMask.replace(targets[i], "%" + (i + 1) + "$s");
    }

    return String.format(outputMask, (Object[])replacements);
}

जिसका सेवन निम्न प्रकार से किया जाएगा:

String story = "Once upon a time, in a foo, there was a foo and a bar.";
story = replace(story, new String[] { "bar", "foo" },
    new String[] { "foo", "bar" }));

3

यह काम करता है और सरल है:

public String replaceBoth(String text, String token1, String token2) {            
    return text.replace(token1, "\ufdd0").replace(token2, token1).replace("\ufdd0", token2);
    }

आप इसे इस तरह उपयोग करते हैं:

replaceBoth("Once upon a time, there was a foo and a bar.", "foo", "bar");

नोट: यह स्ट्रिंग्स पर वर्णों को शामिल नहीं \ufdd0करता है, जो कि यूनिकोड द्वारा आंतरिक उपयोग के लिए स्थायी रूप से आरक्षित एक चरित्र है (देखें http://www.unicode.org/faq/pStreet_use.html ):

मुझे नहीं लगता कि यह आवश्यक है, लेकिन यदि आप बिल्कुल सुरक्षित रहना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:

public String replaceBoth(String text, String token1, String token2) {
    if (text.contains("\ufdd0") || token1.contains("\ufdd0") || token2.contains("\ufdd0")) throw new IllegalArgumentException("Invalid character.");
    return text.replace(token1, "\ufdd0").replace(token2, token1).replace("\ufdd0", token2);
    }

3

केवल एक घटना स्वैपिंग

यदि इनपुट में स्वैपेबल स्ट्रिंग्स में से प्रत्येक की केवल एक घटना होती है, तो आप निम्न कार्य कर सकते हैं:

किसी भी प्रतिस्थापन के लिए आगे बढ़ने से पहले, शब्दों की घटनाओं के संकेत प्राप्त करें। उसके बाद हम केवल इन अनुक्रमों में पाए जाने वाले शब्द को प्रतिस्थापित करते हैं, और सभी घटनाओं को नहीं। इस समाधान का उपयोग करता है StringBuilderऔर मध्यवर्ती Stringएस की तरह उत्पादन नहीं करता है String.replace()

एक बात पर ध्यान दें: यदि स्वैप करने योग्य शब्दों में अलग-अलग लंबाई है, तो पहली जगह के बाद दूसरा सूचकांक बदल सकता है (यदि 1 शब्द 2 से पहले होता है) बिल्कुल 2 लंबाई के अंतर के साथ। इसलिए दूसरे इंडेक्स को संरेखित करने से यह सुनिश्चित होगा कि हम अलग-अलग लंबाई वाले शब्दों को स्वैप कर रहे हैं।

public static String swap(String src, String s1, String s2) {
    StringBuilder sb = new StringBuilder(src);
    int i1 = src.indexOf(s1);
    int i2 = src.indexOf(s2);

    sb.replace(i1, i1 + s1.length(), s2); // Replace s1 with s2
    // If s1 was before s2, idx2 might have changed after the replace
    if (i1 < i2)
        i2 += s2.length() - s1.length();
    sb.replace(i2, i2 + s2.length(), s1); // Replace s2 with s1

    return sb.toString();
}

अवसरों की महत्वाकांक्षी संख्या का स्वैप करना

पिछले मामले के अनुरूप हम सबसे पहले शब्दों के अनुक्रमित (आवृत्तियों) को इकट्ठा करेंगे, लेकिन इस मामले में यह प्रत्येक शब्द के लिए पूर्णांकों की एक सूची होगी, न कि केवल एक int। इसके लिए हम निम्नलिखित उपयोगिता विधि का उपयोग करेंगे:

public static List<Integer> occurrences(String src, String s) {
    List<Integer> list = new ArrayList<>();
    for (int idx = 0;;)
        if ((idx = src.indexOf(s, idx)) >= 0) {
            list.add(idx);
            idx += s.length();
        } else
            return list;
}

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

public static String swapAll(String src, String s1, String s2) {
    List<Integer> l1 = occurrences(src, s1), l2 = occurrences(src, s2);

    StringBuilder sb = new StringBuilder(src);

    // Replace occurrences by decreasing index, alternating between s1 and s2
    for (int i1 = l1.size() - 1, i2 = l2.size() - 1; i1 >= 0 || i2 >= 0;) {
        int idx1 = i1 < 0 ? -1 : l1.get(i1);
        int idx2 = i2 < 0 ? -1 : l2.get(i2);
        if (idx1 > idx2) { // Replace s1 with s2
            sb.replace(idx1, idx1 + s1.length(), s2);
            i1--;
        } else { // Replace s2 with s1
            sb.replace(idx2, idx2 + s2.length(), s1);
            i2--;
        }
    }

    return sb.toString();
}

मुझे यकीन नहीं है कि जावा यूनिकोड को कैसे संभालता है, लेकिन इस कोड का C # बराबर गलत होगा। मुद्दा यह है कि indexOfमैचिंग सबस्ट्रिंग में उतनी लंबाई नहीं हो सकती है, जितना कि यूनिकोड स्ट्रिंग तुल्यता के आइडियोसिंक्रेसिस के लिए सर्चस्ट्रेग धन्यवाद।
कोड्सचैकोस

@CodesInChaos जावा में यह त्रुटिपूर्ण रूप से काम करता है क्योंकि जावा Stringएक चरित्र सरणी है और बाइट सरणी नहीं है। पात्रों के सभी तरीके Stringऔर StringBuilderबाइट्स पर नहीं, जो "एन्कोडिंग-फ्री" हैं, पर काम करते हैं। इस प्रकार indexOfमैचों में खोज तार के समान (चरित्र) लंबाई होती है।
आईसीज़ा

C # और java दोनों में एक स्ट्रिंग UTF-16 कोड इकाइयों का एक क्रम है। मुद्दा यह है कि कोडपॉइंट्स के अलग-अलग क्रम हैं जो यूनिकोड समकक्ष मानते हैं। उदाहरण के लिए äएकल कोडपॉइंट के रूप में या aसंयोजन के बाद अनुसरण किया जा सकता है ¨। कुछ कोडपॉइंट भी हैं जिन्हें अनदेखा किया गया है, जैसे कि शून्य-चौड़ाई (गैर) जॉइनर्स। इससे कोई फर्क नहीं पड़ता कि स्ट्रिंग में बाइट्स, चार्ट्स या जो कुछ भी है, लेकिन जो तुलना नियमों indexOfका उपयोग करता है। यह कोड-यूनिट तुलना ("ऑर्डिनल") द्वारा बस कोड-यूनिट का उपयोग कर सकता है या यह यूनिकोड तुल्यता को लागू कर सकता है। मुझे नहीं पता कि एक जावा ने किसे चुना।
कोडइन्चोस

उदाहरण के लिए "ab\u00ADc".IndexOf("bc")रिटर्न 1.net में दो चरित्र स्ट्रिंग मिलान bcएक तीन चरित्र स्ट्रिंग के लिए।
कोडइन्चोस

1
@CodesInChaos मैं देख रहा हूं कि अब आपका क्या मतलब है। जावा "ab\u00ADc".indexOf("bc")रिटर्न में -1जिसका अर्थ "bc"नहीं मिला "ab\u00ADc"। तो यह अभी भी खड़ा है कि जावा में उपरोक्त एल्गोरिथ्म काम करता है, indexOf()मैचों में खोज तार के समान (चरित्र) लंबाई होती है, और indexOf()केवल रिपोर्ट मेल खाती है यदि चार्ट (कोडपॉइंट्स) मेल खाते हैं।
आईसीज़ा

2

इसका उपयोग करने के लिए एक विधि लिखना आसान है String.regionMatches:

public static String simultaneousReplace(String subject, String... pairs) {
    if (pairs.length % 2 != 0) throw new IllegalArgumentException(
        "Strings to find and replace are not paired.");
    StringBuilder sb = new StringBuilder();
    outer:
    for (int i = 0; i < subject.length(); i++) {
        for (int j = 0; j < pairs.length; j += 2) {
            String find = pairs[j];
            if (subject.regionMatches(i, find, 0, find.length())) {
                sb.append(pairs[j + 1]);
                i += find.length() - 1;
                continue outer;
            }
        }
        sb.append(subject.charAt(i));
    }
    return sb.toString();
}

परिक्षण:

String s = "There are three cats and two dogs.";
s = simultaneousReplace(s,
    "cats", "dogs",
    "dogs", "budgies");
System.out.println(s);

आउटपुट:

तीन कुत्ते और दो दोस्त हैं।

यह तुरंत स्पष्ट नहीं है, लेकिन इस तरह का एक फ़ंक्शन अभी भी उस क्रम पर निर्भर हो सकता है जिसमें प्रतिस्थापन निर्दिष्ट हैं। विचार करें:

String truth = "Java is to JavaScript";
truth += " as " + simultaneousReplace(truth,
    "JavaScript", "Hamster",
    "Java", "Ham");
System.out.println(truth);

आउटपुट:

जावा जावास्क्रिप्ट के रूप में हैम को हम्सटर के रूप में है

लेकिन प्रतिस्थापनों को उल्टा करें:

truth += " as " + simultaneousReplace(truth,
    "Java", "Ham",
    "JavaScript", "Hamster");

आउटपुट:

जावा जावास्क्रिप्ट के रूप में हैम को हैमस्क्रिप्ट के लिए है

ऊप्स! :)

इसलिए यह कभी-कभी सबसे लंबे मैच के लिए सुनिश्चित करने के लिए उपयोगी होता है (जैसा कि PHP का strtrकार्य करता है, उदाहरण के लिए)। विधि का यह संस्करण ऐसा करेगा:

public static String simultaneousReplace(String subject, String... pairs) {
    if (pairs.length % 2 != 0) throw new IllegalArgumentException(
        "Strings to find and replace are not paired.");
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < subject.length(); i++) {
        int longestMatchIndex = -1;
        int longestMatchLength = -1;
        for (int j = 0; j < pairs.length; j += 2) {
            String find = pairs[j];
            if (subject.regionMatches(i, find, 0, find.length())) {
                if (find.length() > longestMatchLength) {
                    longestMatchIndex = j;
                    longestMatchLength = find.length();
                }
            }
        }
        if (longestMatchIndex >= 0) {
            sb.append(pairs[longestMatchIndex + 1]);
            i += longestMatchLength - 1;
        } else {
            sb.append(subject.charAt(i));
        }
    }
    return sb.toString();
}

ध्यान दें कि उपरोक्त विधियाँ केस-संवेदी हैं। यदि आपको केस-असंवेदनशील संस्करण की आवश्यकता है, तो उपरोक्त को संशोधित करना आसान है क्योंकि पैरामीटर String.regionMatchesले सकता है ignoreCase


2

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

public String replace(String sentence, String[]... replace){
    String[] words = sentence.split("\\s+");
    int[] lock = new int[words.length];
    StringBuilder out = new StringBuilder();

    for (int i = 0; i < words.length; i++) {
        for(String[] r : replace){
            if(words[i].contains(r[0]) && lock[i] == 0){
                words[i] = words[i].replace(r[0], r[1]);
                lock[i] = 1;
            }
        }

        out.append((i < (words.length - 1) ? words[i] + " " : words[i]));
    }

    return out.toString();
}

फिर, यह काम पूरा हो गया।

String story = "Once upon a time, there was a foo and a bar.";

String[] a = {"foo", "bar"};
String[] b = {"bar", "foo"};
String[] c = {"there", "Pocahontas"};
story = replace(story, a, b, c);

System.out.println(story); // Once upon a time, Pocahontas was a bar and a foo.

2

आप इनपुट पर कई खोज-प्रतिस्थापित ऑपरेशन कर रहे हैं। यह अवांछित परिणामों का उत्पादन करेगा जब प्रतिस्थापन तारों में खोज के तार होंगे। Foo-> बार, बार-फू उदाहरण पर विचार करें, यहां प्रत्येक पुनरावृत्ति के परिणाम हैं:

  1. एक बार की बात है, एक फू और बार था। (इनपुट)
  2. एक बार की बात है, एक बार और एक बार था। (Foo-> बार)
  3. एक बार की बात है, एक फू ल और फू थी। (बार-> फू, आउटपुट)

आपको वापस जाने के बिना एक पुनरावृत्ति में प्रतिस्थापन करने की आवश्यकता है। एक जानवर बल समाधान इस प्रकार है:

  1. एक मैच मिलने तक कई खोज स्ट्रिंग के लिए वर्तमान स्थिति से अंत तक इनपुट खोजें
  2. मिलान किए गए खोज स्ट्रिंग को संबंधित प्रतिस्थापित स्ट्रिंग से बदलें
  3. प्रतिस्थापित स्ट्रिंग के बाद अगले वर्ण पर वर्तमान स्थिति सेट करें
  4. दोहराना

इस तरह के रूप में एक समारोह String.indexOfAny(String[]) -> int[]{index, whichString}उपयोगी होगा। यहाँ एक उदाहरण है (सबसे कुशल नहीं):

private static String replaceEach(String str, String[] searchWords, String[] replaceWords) {
    String ret = "";
    while (str.length() > 0) {
        int i;
        for (i = 0; i < searchWords.length; i++) {
            String search = searchWords[i];
            String replace = replaceWords[i];
            if (str.startsWith(search)) {
                ret += replace;
                str = str.substring(search.length());
                break;
            }
        }
        if (i == searchWords.length) {
            ret += str.substring(0, 1);
            str = str.substring(1);
        }
    }
    return ret;
}

कुछ परीक्षण:

System.out.println(replaceEach(
    "Once upon a time, there was a foo and a bar.",
    new String[]{"foo", "bar"},
    new String[]{"bar", "foo"}
));
// Once upon a time, there was a bar and a foo.

System.out.println(replaceEach(
    "a p",
    new String[]{"a", "p"},
    new String[]{"apple", "pear"}
));
// apple pear

System.out.println(replaceEach(
    "ABCDE",
    new String[]{"A", "B", "C", "D", "E"},
    new String[]{"B", "C", "E", "E", "F"}
));
// BCEEF

System.out.println(replaceEach(
    "ABCDEF",
    new String[]{"ABCDEF", "ABC", "DEF"},
    new String[]{"XXXXXX", "YYY", "ZZZ"}
));
// XXXXXX
// note the order of search strings, longer strings should be placed first 
// in order to make the replacement greedy

IDEONE पर डेमो, IDEONE पर
डेमो, वैकल्पिक कोड


1

आप इसे हमेशा एक ऐसे शब्द से बदल सकते हैं जिसके बारे में आप सुनिश्चित हैं कि वह स्ट्रिंग में कहीं और दिखाई देगा, और फिर बाद में दूसरी जगह करें:

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar."
story = story.replace("foo", "StringYouAreSureWillNeverOccur").replace("bar", "word2").replace("StringYouAreSureWillNeverOccur", "word1");

ध्यान दें कि "StringYouAreSureWillNeverOccur"ऐसा होने पर यह सही काम नहीं करेगा ।


5
यूनिकोड निजी उपयोग क्षेत्र, U + E000..U + F8FF के पात्रों का उपयोग करें, एक StringThatCannotEverOccur बना रहे हैं। इनपुट में मौजूद नहीं होने के कारण आप उन्हें पहले ही फ़िल्टर कर सकते हैं।
डेविड कॉनरेड

या यू + एफडीडी0..यू + एफडीईएफ, "नॉनचैकर्स", जो आंतरिक उपयोग के लिए आरक्षित हैं।
डेविड कॉनरैड

1

StringBuilder का उपयोग करने पर विचार करें

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

String firstString = "???";
String secondString  = "???"

StringBuilder story = new StringBuilder("One upon a time, there was a " 
    + firstString
    + " and a "
    + secondString);

int  firstWord = 30;
int  secondWord = firstWord + firstString.length() + 7;

story.replace(firstWord, firstWord + firstString.length(), userStringOne);
story.replace(secondWord, secondWord + secondString.length(), userStringTwo);

firstString = userStringOne;
secondString = userStringTwo;

return story;

1

जो मैं केवल साझा कर सकता हूं वह मेरा अपना तरीका है।

आप एक अस्थायी String temp = "<?>";या का उपयोग कर सकते हैंString.Format();

यह मेरा उदाहरण कोड है जो कंसोल एप्लिकेशन के माध्यम से बनाया गया है - "आइडिया ओनली, नॉट एक्सक्लूसिव आंसर"

static void Main(string[] args)
    {
        String[] word1 = {"foo", "Once"};
        String[] word2 = {"bar", "time"};
        String story = "Once upon a time, there was a foo and a bar.";

        story = Switcher(story,word1,word2);
        Console.WriteLine(story);
        Console.Read();
    }
    // Using a temporary string.
    static string Switcher(string text, string[] target, string[] value)
    {
        string temp = "<?>";
        if (target.Length == value.Length)
        {
            for (int i = 0; i < target.Length; i++)
            {
                text = text.Replace(target[i], temp);
                text = text.Replace(value[i], target[i]);
                text = text.Replace(temp, value[i]);
            }
        }
        return text;
    }

या आप भी उपयोग कर सकते हैं String.Format();

static string Switcher(string text, string[] target, string[] value)
        {
            if (target.Length == value.Length)
            {
                for (int i = 0; i < target.Length; i++)
                {
                    text = text.Replace(target[i], "{0}").Replace(value[i], "{1}");
                    text = String.Format(text, value[i], target[i]);
                }
            }
            return text;
        }

आउटपुट: time upon a Once, there was a bar and a foo.


यह बहुत हैकी है। यदि वह "_" को बदलना चाहता है तो आप क्या करेंगे?
पियर-एलेक्जेंडर ब्यूचर्ड

@ पियर-AlexandreBouchard में तरीकों मैं का मूल्य बदल tempसे "_"में <?>। लेकिन यदि आवश्यक हो, तो वह जो कर सकता है वह है एक और पैरामीटर को उस विधि में जोड़ना जो अस्थायी को बदल देगा। - "इसे सरल रखना सही है?"
लियोनेल सरमियोनो

मेरा कहना है कि योन अपेक्षित परिणाम की गारंटी नहीं दे सकता है क्योंकि यदि अस्थायी == को प्रतिस्थापित किया जाता है, तो आपका तरीका काम नहीं करेगा।
पियर-एलेक्जेंडर बुचर्ड

1

यहाँ मेरा संस्करण है, जो शब्द-आधारित है:

class TextReplace
{

    public static void replaceAll (String text, String [] lookup,
                                   String [] replacement, String delimiter)
    {

        String [] words = text.split(delimiter);

        for (int i = 0; i < words.length; i++)
        {

            int j = find(lookup, words[i]);

            if (j >= 0) words[i] = replacement[j];

        }

        text = StringUtils.join(words, delimiter);

    }

    public static  int find (String [] array, String key)
    {

        for (int i = 0; i < array.length; i++)
            if (array[i].equals(key))
                return i;

        return (-1);

    }

}

1
String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar."

थोड़ा मुश्किल तरीका है लेकिन आपको कुछ और जाँच करने की ज़रूरत है।

1. सरणी से चरित्र सरणी के लिए

   String temp[] = story.split(" ");//assume there is only spaces.

2. अस्थायी पर और fooसाथ में barऔर फिर से बदली स्ट्रिंग प्राप्त करने की कोई संभावना नहीं है के barसाथ बंद करो foo


1

खैर, छोटा जवाब है ...

String word1 = "bar";
String word2 = "foo";
String story = "Once upon a time, there was a foo and a bar.";
story = story.replace("foo", "@"+ word1).replace("bar", word2).replace("@" + word2, word1);
System.out.println(story);

1

यहां दिए गए उत्तर का उपयोग करके आप उन स्ट्रिंग के सभी घटनाओं को पा सकते हैं जिन्हें आप बदलना चाहते हैं।

इसलिए उदाहरण के लिए आप उपरोक्त SO उत्तर में कोड चलाते हैं। अनुक्रमणिका की दो तालिकाएँ बनाएँ (मान लें कि बार और फू आपके स्ट्रिंग में केवल एक बार दिखाई नहीं देते हैं) और आप अपनी स्ट्रिंग में उन्हें बदलने पर उन तालिकाओं के साथ काम कर सकते हैं।

अब विशिष्ट सूचकांक स्थानों पर प्रतिस्थापित करने के लिए जिनका आप उपयोग कर सकते हैं:

public static String replaceStringAt(String s, int pos, String c) {
   return s.substring(0,pos) + c + s.substring(pos+1);
}

जबकि posसूचकांक वह जगह है जहां आपके तार शुरू होते हैं (ऊपर बताए गए सूचकांक तालिकाओं से)। तो मान लें कि आपने प्रत्येक के लिए अनुक्रमणिका की दो तालिकाएँ बनाई हैं। चलो उन्हें बुलाओ indexBarऔर indexFoo

अब उन्हें बदलने में आप बस दो छोरों को चला सकते हैं, प्रत्येक प्रतिस्थापन के लिए एक जिसे आप बनाना चाहते हैं।

for(int i=0;i<indexBar.Count();i++)
replaceStringAt(originalString,indexBar[i],newString);

इसी तरह एक और लूप के लिए indexFoo

यह अन्य उत्तरों की तरह कुशल नहीं हो सकता है, लेकिन मैप्स या अन्य सामानों की तुलना में इसे समझना सरल है।

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

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


-1

मैंने यह कोड विकसित किया है जिससे समस्या हल हो जाएगी:

public static String change(String s,String s1, String s2) {
   int length = s.length();
   int x1 = s1.length();
   int x2 = s2.length();
   int x12 = s.indexOf(s1);
   int x22 = s.indexOf(s2);
   String s3=s.substring(0, x12);
   String s4 =s.substring(x12+3, x22);
   s=s3+s2+s4+s1;
   return s;
}

मुख्य उपयोग में change(story,word2,word1).


2
यह केवल तभी काम करेगा जब प्रत्येक तार की एक उपस्थिति हो
विक

-1
String word1 = "bar";
String word2 = "foo";

String story = "Once upon a time, there was a foo and a bar."

story = story.replace("foo", "<foo />");
story = story.replace("bar", "<bar />");

story = story.replace("<foo />", word1);
story = story.replace("<bar />", word2);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.