Reputation: 357
I have a input string like -
abbdabab
How to replace only the 2nd, 3rd and subsequent occurances of the substring "ab"
with any random string like "x"
keeping the original string intact. Example in this case -
1st Output - xbdabab 2nd Output - abbdxab 3rd Output - abbdabx and so on...
I have tried using Regex like -
int occCount = Regex.Matches("abbdabab", "ab").Count;
if (occCount > 1)
{
for (int i = 1; i <= occCount; i++)
{
Regex regReplace = new Regex("ab");
string modifiedValue = regReplace.Replace("abbdabab", "x", i);
//decodedMessages.Add(modifiedValue);
}
}
Here I am able to get the 1st output when the counter i
value is 1
but not able to get the subsequent results. Is there any overloaded Replace
method which could achieve this ? Or Can anyone help me in pointing where I might have gone wrong?
Upvotes: 0
Views: 404
Reputation: 627128
You may use a dynamically built regex to be used with regex.Replace
directly:
var s = "abbdabab";
var idx = 1; // First = 1, Second = 2
var search = "ab";
var repl = "x";
var pat = new Regex($@"(?s)((?:{search}.*?){{{idx-1}}}.*?){search}"); // ((?:ab.*?){0}.*?)ab
Console.WriteLine(pat.Replace(s, $"${{1}}{repl}", 1));
See the C# demo
The pattern will look like ((?:ab.*?){0}.*?)ab
and will match
(?s)
- RegexOptions.Singleline
to make .
also match newlines((?:ab.*?){0}.*?)
- Group 1 (later, this value will be put back into the result with ${1}
backreference)
(?:ab.*?){0}
- 0 occurrences of ab
followed with any 0+ chars as few as possible.*?
- any 0+ chars as few as possibleab
- the search string/pattern.The last argument to pat.Replace
is 1
, so that only the first occurrence could be replaced.
If search
is a literal text, you need to use var search = Regex.Escape("a+b");
.
If the repl
can have $
, add repl = repl.Replace("$", "$$");
.
Upvotes: 0
Reputation: 273135
You can use a StringBuilder
:
string s = "abbdabab";
var matches = Regex.Matches(s, "ab");
StringBuilder sb = new StringBuilder(s);
var m = matches[0]; // 0 for first output, 1 for second output, and so on
sb.Remove(m.Index, m.Length);
sb.Insert(m.Index, "x");
var result = sb.ToString();
Console.WriteLine(result);
Upvotes: 1
Reputation: 186813
You can try IndexOf
instead of regular expressions:
string source = "abbdabab";
string toFind = "ab";
string toSet = "X";
for (int index = source.IndexOf(toFind);
index >= 0;
index = source.IndexOf(toFind, index + 1)) {
string result = source.Substring(0, index) +
toSet +
source.Substring(index + toFind.Length);
Console.WriteLine(result);
}
Outcome:
Xbdabab
abbdXab
abbdabX
Upvotes: 2