RegEx en C # para el valor get
-
28-09-2019 - |
Pregunta
No tengo ningún texto en C #, y necesito "compatibles" con el uso de expresiones regulares, y obtener un valor (analizar el texto para obtener el valor).
Textos:
var asunto1 = "ID P20101125_0003 - Pendiente de autorización f - ";
var asunto2 = "ID P20101125_0003 cualquier t Cualquier texto ";
var asunto3 = "ID_P20101125_0003 cualquier t Cualquier texto ";
Necesito obtener el valor:
var peticion = "P20101125_0003";
Tengo esta expresión regular, pero no para mí:
//ID P20101125_0003 -- Pendiente de autorización --
patternPeticionEV.Append(@"^");
patternPeticionEV.Append(@"ID P");
patternPeticionEV.Append(@"(20[0-9][0-9])"); // yyyy
patternPeticionEV.Append(@"(0[1-9]|1[012])"); // MM
patternPeticionEV.Append(@"(0[1-9]|[12][0-9]|3[01])"); // dd
patternPeticionEV.Append(@"(_)");
patternPeticionEV.Append(@"\d{4}");
//patternPeticionEV.Append(@"*");
patternPeticionEV.Append(@"$");
if (System.Text.RegularExpressions.Regex.IsMatch(asuntoPeticionEV, exprRegular, System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
var match = System.Text.RegularExpressions.Regex.Match(asuntoPeticionEV, exprRegular, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
//...
}
Solución
Sus extremos de expresiones regulares con "$", que dice "la línea / texto tiene que terminar allí". Usted no quiere eso. Sólo deshacerse de esta línea:
patternPeticionEV.Append(@"$");
y se trabajará sobre todo de inmediato. A continuación, sólo tiene que añadir un grupo de captura para aislar el fragmento de texto que desea.
También me gustaría recomendar la adición de using System.Text.RegularExpressions;
de modo que usted no tiene que calificar totalmente Regex
cada vez. También puede llamar a Match
y luego comprobar si hay éxito, para evitar a juego dos veces.
Código de ejemplo:
using System.Text.RegularExpressions;
class Test
{
static void Main()
{
DisplayMatch("ID P20101125_0003 -- Pendiente de autorización --");
// No match due to _
DisplayMatch("ID_P20101125_0003 any text any text");
}
static readonly Regex Pattern = new Regex
("^" + // Start of string
"ID " +
"(" + // Start of capturing group
"P" +
"(20[0-9][0-9])" + // yyyy
"(0[1-9]|1[012])" + // MM
"(0[1-9]|[12][0-9]|3[01])" + // dd
@"_\d{4}" +
")" // End of capturing group
);
static void DisplayMatch(string input)
{
Match match = Pattern.Match(input);
if (match.Success)
{
Console.WriteLine("Matched: {0}", match.Groups[1]);
}
else
{
Console.WriteLine("No match");
}
}
}
Otros consejos
Esto podría ser sólo yo, sino para cosas como analizar cadenas en valores significativos prefiero hacer algo más detallado de esta manera:
private bool TryParseContent(string text, out DateTime date, out int index)
{
date = DateTime.MinValue;
index = -1;
if (text.Length < 17)
return false;
string idPart = text.Substring(0, 4);
if (idPart != "ID_P" && idPart != "ID P")
return false;
string datePart = text.Substring(4, 8);
if (!DateTime.TryParseExact(datePart, "yyyyMMdd", System.Globalization.DateTimeFormatInfo.InvariantInfo, System.Globalization.DateTimeStyles.None, out date))
return false;
// TODO: do additional validation of the date
string indexPart = text.Substring(13, 4);
if (!int.TryParse(indexPart, out index))
return false;
return true;
}
¿Por qué no usar subcadena, como a continuación:
var asunto1 = "ID P20101125_0003 -- Pendiente de autorización --";
var asunto2 = "ID P20101125_0003 any text any text";
var asunto3 = "ID_P20101125_0003 any text any text";
var peticion = asunto1.Substring(3,14); //gets P20101125_0003
Esta expresión regular le dará deseado cadena
^ID[_ ]P[0-9_]+?