Reputation: 171
If I have a varying regular expression that could look like any of the following patterns:
(.{2})(?<somedigit>\d+)(.{5})
(?<somedigit>\d+)(.{7})
(.{1})(?<somedigit>\d+)
and I want to replace the somedigit capture group with any number, and leave everything else untouched, how would I do that (say in C# or Java)?
For instance, say I have this text:
QB2-G456
and I use this regex:
(.{2})(?<somedigit>\d+)(.{5})
to match it, and say I want to replace the somedigit with 35, to get this final result:
QB35-G456
I know I can use this replacement text:
${1}35${2}
But the root of my question is that I do not know the format of my regular expression upfront. So I cannot hard code the capture group references for the text I do not want to change, as there could be different variations.
Since multiple numbers may be present I cannot just replace \d+ as I do not know whether the numbers are in the beginning or end or middle and whether other numbers are present further-on in the text.
Ideally I was hoping for something like:
new Regex("(.{2})(?<somedigit>\d+)(.{5})").ReplaceCaptureGroup("QB2-G456", "somedigit", "35")
and have everything pass through unmodified except the somedigit capture group that is replaced.
I searched for similar issues and only found solutions to where the regex is fixed and known, as already explained above.
Upvotes: 4
Views: 830
Reputation: 626826
Here is how you can do it in C#:
var str1 = "QB2-G456";
var rx1 = new Regex(@"(.{2})(?<somedigit>\d+)(.{5})");
var res = rx1.Replace(str1, m => m.Value.Replace(m.Groups["somedigit"].Value, "35"));
// Result: QB35-G35456
This will replace all occurrences of the "somedigit" group contents inside the string (i.e. QB2-G2456
will turn into QB35-G35456
). To work around this, use a Regex.Replace(input, regex, repl, numOfReplacements)
or this method:
public string ReplaceOnceAtIndex(string text, string search, string replace, int index)
{
if (index < 0)
return text;
return text.Substring(0, index) + replace + text.Substring(index + search.Length);
}
// ... And thenin the caller ...
var res2 = rx1.Replace(str1, m =>
ReplaceOnceAtIndex(m.Value, m.Groups["somedigit"].Value, "35", m.Groups["somedigit"].Index));
// Result: QB35-G2456
Upvotes: 2