Replace only some groups with Regex
假设我有以下regex:
1 | -(\d+)- |
我想用c_将1组
1 | -AA- |
现在我用以下方法替换它:
1 2 3 | var text ="example-123-example"; var pattern = @"-(\d+)-"; var replaced = Regex.Replace(text, pattern,"-AA-"); |
但我不太喜欢这样,因为如果我改变模式来匹配
我在找类似的东西:
保持匹配文本的精确性,但是用
编辑:这只是一个例子。我只是在寻找一种做我上面所说的事情的通用方法。
它应该适用于:
我所要做的就是只替换组,并保留其余的匹配项。
一个好主意是将组内的所有内容封装起来,不管是否需要识别它们。这样就可以在替换字符串中使用它们。例如:
1 2 | var pattern = @"(-)(\d+)(-)"; var replaced = Regex.Replace(text, pattern,"$1AA$3"); |
或者使用MatchEvaluator:
1 | var replaced = Regex.Replace(text, pattern, m => m.Groups[1].Value +"AA" + m.Groups[3].Value); |
另一种稍有混乱的方法可能是使用后向/前向:
您可以使用lookahead和lookbehind执行此操作:
1 2 | var pattern = @"(?<=-)\d+(?=-)"; var replaced = Regex.Replace(text, pattern,"AA"); |
我还需要这个,为此我创建了以下扩展方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public static class RegexExtensions { public static string ReplaceGroup( this Regex regex, string input, string groupName, string replacement) { return regex.Replace( input, m => { var group = m.Groups[groupName]; var sb = new StringBuilder(); var previousCaptureEnd = 0; foreach (var capture in group.Captures.Cast<Capture>()) { var currentCaptureEnd = capture.Index + capture.Length - m.Index; var currentCaptureLength = capture.Index - m.Index - previousCaptureEnd; sb.Append( m.Value.Substring( previousCaptureEnd, currentCaptureLength)); sb.Append(replacement); previousCaptureEnd = currentCaptureEnd; } sb.Append(m.Value.Substring(previousCaptureEnd)); return sb.ToString(); }); } } |
用途:
1 2 3 4 5 | var input = @"[assembly: AssemblyFileVersion(""2.0.3.0"")][assembly: AssemblyFileVersion(""2.0.3.0"")]"; var regex = new Regex(@"AssemblyFileVersion\(""(?<version>(\d+\.?){4})""\)"); var result = regex.ReplaceGroup(input ,"version","1.2.3"); |
结果:
1 | [assembly: AssemblyFileVersion("1.2.3")][assembly: AssemblyFileVersion("1.2.3")] |
如果不想更改模式,可以使用匹配组的组索引和长度属性。
1 2 3 4 5 6 7 8 | var text ="example-123-example"; var pattern = @"-(\d+)-"; var regex = new RegEx(pattern); var match = regex.Match(text); var firstPart = text.Substring(0,match.Groups[1].Index); var secondPart = text.Substring(match.Groups[1].Index + match.Groups[1].Length); var fullReplace = firstPart +"AA" + secondPart; |
这是另一个不错的干净选择,不需要改变你的模式。
1 2 3 4 5 6 7 8 9 | var text ="example-123-example"; var pattern = @"-(\d+)-"; var replaced = Regex.Replace(text, pattern, (_match) => { Group group = _match.Groups[1]; string replace ="AA"; return String.Format("{0}{1}{2}", _match.Value.Substring(0, group.Index - _match.Index), replace, _match.Value.Substring(group.Index - _match.Index + group.Length)); }); |
进行下面的编码以获得单独的组更换。
1 2 3 4 5 6 7 8 9 | new_bib = Regex.Replace(new_bib, @"(?s)(\\bibitem\[[^\]]+\]\{" + pat4 + @"\})[\s \v]*([\\\{\}a-zA-Z\.\s\,\;\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\" + dblqt + @"\\\;\\\`\\']{20,70})", delegate(Match mts) { var fg = mts.Groups[0].Value.ToString(); var fs = mts.Groups[1].Value.ToString(); var fss = mts.Groups[2].Value.ToString(); fss = Regex.Replace(fss, @"[\\\{\}\\\#\\\$\\\%\\\&\*\@\\\!\\\^+\-\\\=\\\~\\\:\\" + dblqt + @"\\\;\\\`\\']+",""); return"" + fss +"</augroup>" + fs; }, RegexOptions.IgnoreCase); |