uso sharp regulares expresiones c# regex replace

c# - sharp - Reemplaza solo algunos grupos con Regex



replace c# expresiones regulares (6)

Supongamos que tengo la siguiente expresión regular:

-(/d+)-

y quiero reemplazar, usando C #, el Grupo 1 (/d+) con AA , para obtener:

-AA-

Ahora lo estoy reemplazando usando:

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

Pero realmente no me gusta esto, porque si cambio el patrón para que coincida con _(/d+)_ lugar, tendré que cambiar la cadena de reemplazo por _AA_ también, y esto va en contra del principio DRY.

Estoy buscando algo como:

Mantenga el texto coincidente exactamente como está, pero cambie el Grupo 1 por this text y el Grupo 2 por another text ...

Editar:
Eso fue solo un ejemplo. Solo busco una manera genérica de hacer lo que dije arriba.

Debería funcionar para:

anything(/d+)more_text y cualquier patrón que puedas imaginar.

Todo lo que quiero hacer es reemplazar solo grupos, y mantener el resto del partido.


Aquí hay otra opción de limpieza agradable que no requiere cambiar su patrón.

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


Puedes hacer esto usando lookahead y lookbehind :

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


Si no desea cambiar su patrón, puede usar las propiedades Índice de grupo y Longitud de un grupo coincidente.

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;


También tuve necesidad de esto y creé el siguiente método de extensión para él:

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

Uso:

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

Resultado:

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


Una buena idea podría ser encapsular todo dentro de los grupos, sin importar si es necesario identificarlos o no. De esa forma puedes usarlos en tu cadena de reemplazo. Por ejemplo:

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

Otra forma, un poco desordenada, podría ser utilizar un lookbehind / lookahead:

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


siga la codificación a continuación para obtener el reemplazo de grupo por separado.

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 "<augroup>" + fss + "</augroup>" + fs; }, RegexOptions.IgnoreCase);