2

I want to replace n occurrence of a substring in a string.

myString = "I have a mobile. I have a cat.";

How I can replace the second have of myString

5 Answers 5

2

hope this simple function helps. You can also extract the function contents if you don't wish a function. It's just two lines with some Dart magic

void main() {
  String myString = 'I have a mobile. I have a cat.';
  String searchFor='have';
  int replaceOn = 2;
  String replaceText = 'newhave';
  String result = customReplace(myString,searchFor,replaceOn,replaceText);
  print(result);
}

String customReplace(String text,String searchText, int replaceOn, String replaceText){
  Match result = searchText.allMatches(text).elementAt(replaceOn - 1);
  return text.replaceRange(result.start,result.end,replaceText);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Be aware that's that solution is not optimal. For example, if the string contains 100 occurrences and you are replacing the fifth one, then this code will search for all occurrences and only then replace the fifth one.
I doubt that because allMatches() returns a lazy iterable. So it computes only the requested record. correct me if I wrong
Looks like you are right👍. Also, I should mention that if searchText is not found your function will throw an exception.
yes my friend. this is not a production ready code. just giving the core concept. that's all
2

This would be a better solution to undertake as it check the fallbacks also. Let me list down all the scenarios:

  1. If position is 0 then it will replace all occurrence.
  2. If position is correct then it will replace at same location.
  3. If position is wrong then it will send back input string.
  4. If substring does not exist in input then it will send back input string.

void main() {
          String input = "I have a mobile. I have a cat.";
          print(replacenth(input, 'have', 'need', 1));
        }
        
        /// Computes the nth string replace.
        String replacenth(String input, String substr, String replstr,int position) {
          
          if(input.contains(substr))
          {
            var splittedStr = input.split(substr);
            if(splittedStr.length == 0)
              return input;
              
            String finalStr = "";
            
            for(int i = 0; i < splittedStr.length; i++)
            {
              finalStr += splittedStr[i];
              if(i == (position - 1))
                finalStr += replstr;
              else if(i < (splittedStr.length - 1))
                finalStr += substr;
            }
            
            return finalStr;
          }
          
          return input;
        }

Comments

1

Something like that should work:

String replaceNthOccurrence(String input, int n, String from, String to) {
  var index = -1;
  
  while (--n >= 0) {
    index = input.indexOf(from, ++index);
    if (index == -1) {
      break;
    }
  }
  
  if (index != -1) {
    var result = input.replaceFirst(from, to, index);
    return result;
  }
  
  return input;
} 

void main() {
   var myString = "I have a mobile. I have a cat.";
   var replacedString = replaceNthOccurrence(myString, 2, "have", "had");
   print(replacedString); // prints "I have a mobile. I had a cat."
}

Comments

1

let's try with this

void main() {
  var myString = "I have a mobile. I have a cat.I have a cat";
  print(replaceInNthOccurrence(myString, "have", "test", 1));
}

String replaceInNthOccurrence(
    String stringToChange, String searchingWord, String replacingWord, int n) {
  if(n==1){
    return stringToChange.replaceFirst(searchingWord, replacingWord);
  }
  final String separator = "#######";
  
  String splittingString =
      stringToChange.replaceAll(searchingWord, separator + searchingWord);
  var splitArray = splittingString.split(separator);
  print(splitArray);
  String result = "";
  for (int i = 0; i < splitArray.length; i++) {
    if (i % n == 0) {
      splitArray[i] = splitArray[i].replaceAll(searchingWord, replacingWord);
    }
    result += splitArray[i];
  }
  return result;
}

here the regex

void main() {
  var myString = "I have a mobile. I have a cat. I have a cat. I have a cat.";
   final newString =
      myString.replaceAllMapped(new RegExp(r'^(.*?(have.*?){3})have'), (match) {
    return '${match.group(1)}';
  });
  
  print(newString.replaceAll("  "," had "));
}

Demo link

1 Comment

@MohammadAliRony please check the regex magic and demo link regex101.com/r/wP7pR2/52
1

Here it is one more variant which allows to replace any occurrence in subject string.

void main() {
  const subject = 'I have a dog. I have a cat. I have a bird.';
  final result = replaceStringByOccurrence(subject, 'have', '*have no*', 0);
  print(result);
}

/// Looks for `occurrence` of `search` in `subject` and replace it with `replace`.
///
/// The occurrence index is started from 0.
String replaceStringByOccurrence(
    String subject, String search, String replace, int occurence) {
  if (occurence.isNegative) {
    throw ArgumentError.value(occurence, 'occurrence', 'Cannot be negative');
  }
  final regex = RegExp(r'have');
  final matches = regex.allMatches(subject);
  if (occurence >= matches.length) {
    throw IndexError(occurence, matches, 'occurrence',
        'Cannot be more than count of matches');
  }
  int index = -1;
  return subject.replaceAllMapped(regex, (match) {
    index += 1;
    return index == occurence ? replace : match.group(0)!;
  });
}

Tested on dartpad.

1 Comment

I think this is not a case at least for negative occurrence because logical error (no negative indicies). Actually it is better to use assert here. For second one it is possible to return the original string. And this is not the complete solution but only a piece of code to solve the requested task. Anyone is free to modify the code on their wish.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.