regularexpressions - Cuenta regex reemplaza(C#)
vb net regular expressions (3)
¿Hay alguna forma de contar la cantidad de reemplazos que hace un Regex? ¿Reemplazar?
Por ejemplo, para Regex.Replace("aaa", "a", "b");
Quiero obtener el número 3 (el resultado es "bbb"
); para Regex.Replace("aaa", "(?<test>aa?)", "${test}b");
Quiero obtener el número 2 (el resultado es "aabab"
).
Formas en que puedo pensar para hacer esto:
- Use un MatchEvaluator que incremente una variable capturada, haciendo el reemplazo manualmente
- Obtenga un MatchCollection e itérelo, haciendo el reemplazo manualmente y manteniendo un recuento
- Busque primero y obtenga un MatchCollection, obtenga el conteo de eso, luego haga un reemplazo separado
Los métodos 1 y 2 requieren el análisis manual de los reemplazos de $, el método 3 requiere expresiones regulares que coincidan con la cadena dos veces. ¿Hay una mejor manera?
Esto debería hacerlo.
int count = 0;
string text = Regex.Replace(text,
@"(((http|ftp|https):////|www/.)[/w/-_]+(/.[/w/-_]+)+([/w/-/.,@?^=%&:/~/+#]*[/w/-/@?^=%&/~/+#])?)", //Example expression. This one captures URLs.
match =>
{
string replacementValue = String.Format("<a href=''{0}''>{0}</a>", match.Value);
count++;
return replacementValue;
});
No estoy en mi computadora dev, así que no puedo hacerlo ahora, pero voy a experimentar más tarde y ver si hay una forma de hacerlo con expresiones lambda en lugar de declarar el método IncrementCount () solo para incrementar un int .
Se modificó EDIT para usar una expresión lambda en lugar de declarar otro método.
EDIT2 Si no conoce el patrón de antemano, aún puede obtener todas las agrupaciones (los $ grupos a los que hace referencia) dentro del objeto coincidente, ya que se incluyen como una Colección de grupo. Al igual que:
int count = 0;
string text = Regex.Replace(text,
@"(((http|ftp|https):////|www/.)[/w/-_]+(/.[/w/-_]+)+([/w/-/.,@?^=%&:/~/+#]*[/w/-/@?^=%&/~/+#])?)", //Example expression. This one captures URLs.
match =>
{
string replacementValue = String.Format("<a href=''{0}''>{0}</a>", match.Value);
count++;
foreach (Group g in match.Groups)
{
g.Value; //Do stuff with g.Value
}
return replacementValue;
});
Gracias tanto a Chevex como a Guffa. Comencé a buscar una mejor manera de obtener los resultados y descubrí que hay un método de Resultado en la clase de Match que hace la sustitución. Esa es la pieza faltante del rompecabezas. Código de ejemplo a continuación:
using System.Text.RegularExpressions;
namespace regexrep
{
class Program
{
static int Main(string[] args)
{
string fileText = System.IO.File.ReadAllText(args[0]);
int matchCount = 0;
string newText = Regex.Replace(fileText, args[1],
(match) =>
{
matchCount++;
return match.Result(args[2]);
});
System.IO.File.WriteAllText(args[0], newText);
return matchCount;
}
}
}
Con un archivo test.txt que contiene aaa, la línea de comandos regexrep test.txt "(?<test>aa?)" ${test}b
establecerá% errorlevel% en 2 y cambiará el texto a aabab.
Puede usar un MatchEvaluator
que se ejecuta para cada reemplazo, de esa manera puede contar cuántas veces ocurre:
int cnt = 0;
string result = Regex.Replace("aaa", "a", m => {
cnt++;
return "b";
});
El segundo caso es más complicado ya que tiene que producir el mismo resultado que el patrón de reemplazo:
int cnt = 0;
string result = Regex.Replace("aaa", "(?<test>aa?)", m => {
cnt++;
return m.Groups["test"] + "b";
});