Me está costando encontrar un buen recurso que explique cómo usar Grupos de captura con nombre en C #. Este es el código que tengo hasta ahora:
string page = Encoding.ASCII.GetString(bytePage);
Regex qariRegex = new Regex("<td><a href=\"(?<link>.*?)\">(?<name>.*?)</a></td>");
MatchCollection mc = qariRegex.Matches(page);
CaptureCollection cc = mc[0].Captures;
MessageBox.Show(cc[0].ToString());
Sin embargo, esto siempre muestra la línea completa:
<td><a href="/path/to/file">Name of File</a></td>
He experimentado con varios otros "métodos" que he encontrado en varios sitios web, pero sigo obteniendo el mismo resultado.
¿Cómo puedo acceder a los grupos de captura con nombre que se especifican en mi expresión regular?
<>
lo romperá. Puede usar(?'link'.*)
en su lugar en este caso. No es del todo relevante para esta pregunta, pero llegué aquí desde una búsqueda en Google de "grupos de captura con nombre .net", así que estoy seguro de que otras personas también lo están ...<>
, no lo romperá. Pude usar lamyRegex.GetGroupNames()
colección como nombres de elementos XML.Respuestas:
Utilice la colección de grupo del objeto Match, indizándolo con el nombre del grupo de captura, p. Ej.
fuente
var m
, ya que eso sería unobject
.Puede especificar la cadena del grupo de captura con nombre pasándola al indizador de la
Groups
propiedad de unMatch
objeto resultante .Aquí hay un pequeño ejemplo:
fuente
El siguiente ejemplo de código coincidirá con el patrón incluso en el caso de caracteres de espacio en el medio. es decir:
tanto como:
El método devuelve verdadero o falso, dependiendo de si la cadena de entrada htmlTd coincide con el patrón o no. Si coincide, los parámetros de salida contienen el enlace y el nombre respectivamente.
He probado esto y funciona correctamente.
fuente
${1}
para mantener las cosas aún más simples.Además, si alguien tiene un caso de uso donde necesita nombres de grupo antes de ejecutar la búsqueda en el objeto Regex, puede usar:
fuente
Esta respuesta mejora con la respuesta de Rashmi Pandit , que es de alguna manera mejor que el resto porque parece resolver completamente el problema exacto detallado en la pregunta.
Lo malo es que es ineficiente y no usa la opción IgnoreCase de manera consistente.
La parte ineficiente se debe a que la expresión regular puede ser costosa de construir y ejecutar, y en esa respuesta podría haber sido construida solo una vez (la llamada
Regex.IsMatch
fue simplemente construir la expresión regular de nuevo detrás de la escena). YMatch
método podría haber sido llamado una sola vez y se almacena en una variable y, a continuaciónlink
, yname
debe llamarResult
de esa variable.Y la opción IgnoreCase solo se usó en la
Match
parte pero no en laRegex.IsMatch
parte.También moví la definición de Regex fuera del método para construirla solo una vez (creo que es el enfoque sensato si estamos almacenando el ensamblaje con la
RegexOptions.Compiled
opción).fuente