Sostituisci solo alcuni gruppi con Regex

Supponiamo di avere la seguente espressione regolare:

-(\d+)- 

e voglio sostituire, usando C #, il Gruppo 1 (\d+) con AA , per ottenere:

 -AA- 

Ora lo sto sostituendo usando:

 var text = "example-123-example"; var pattern = @"-(\d+)-"; var replaced = Regex.Replace(text, pattern, "-AA-"); 

Ma non mi piace molto, perché se cambio il pattern in modo che corrisponda a _(\d+)_ , dovrò cambiare anche la stringa di sostituzione di _AA_ , e questo è contro il principio DRY.

Sto cercando qualcosa come:

Mantieni il testo corrispondente esattamente come è, ma cambia il Gruppo 1 con this text e il Gruppo 2 con another text

Modificare:
Quello era solo un esempio. Sto solo cercando un modo generico di fare ciò che ho detto sopra.

Dovrebbe funzionare per:

anything(\d+)more_text e qualsiasi modello che si possa immaginare.

Tutto quello che voglio fare è sostituire solo i gruppi e mantenere il resto della partita.

Una buona idea potrebbe essere quella di incapsulare tutto all’interno dei gruppi, non importa se è necessario identificarli o meno. In questo modo puoi usarli nella tua stringa di sostituzione. Per esempio:

 var pattern = @"(-)(\d+)(-)"; var replaced = Regex.Replace(text, pattern, "$1AA$3"); 

o usando un MatchEvaluator:

 var replaced = Regex.Replace(text, pattern, m => m.Groups[1].Value + "AA" + m.Groups[3].Value); 

Un altro modo, leggermente disordinato, potrebbe essere l’utilizzo di un lookbehind / lookahead:

(?<=-)(\d+)(?=-)

Puoi farlo usando lookahead e lookbehind :

 var pattern = @"(?<=-)\d+(?=-)"; var replaced = Regex.Replace(text, pattern, "AA"); 

Avevo anche bisogno di questo e ho creato il seguente metodo di estensione per questo:

 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()) { 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(); }); } } 

Uso:

 var input = @"[assembly: AssemblyFileVersion(""2.0.3.0"")][assembly: AssemblyFileVersion(""2.0.3.0"")]"; var regex = new Regex(@"AssemblyFileVersion\(""(?(\d+\.?){4})""\)"); var result = regex.ReplaceGroup(input , "version", "1.2.3"); 

Risultato:

 [assembly: AssemblyFileVersion("1.2.3")][assembly: AssemblyFileVersion("1.2.3")] 

Se non si desidera modificare il modello, è ansible utilizzare le proprietà Indice di gruppo e Lunghezza di un gruppo con corrispondenza.

 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; 

Ecco un’altra bella opzione pulita che non richiede la modifica del modello.

  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)); }); 

passare attraverso la codifica qui sotto per ottenere la sostituzione del gruppo separato.

 new_bib = Regex.Replace(new_bib, @"(?s)(\\bibitem\[[^\]]+\]\{" + pat4 + @"\})[\s\n\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 + "" + fs; }, RegexOptions.IgnoreCase);