web-dev-qa-db-fra.com

Comment accéder aux groupes de capture nommés dans une Regex .NET?

J'ai de la difficulté à trouver une bonne ressource qui explique comment utiliser les groupes de capture nommée en C #. C'est le code que j'ai jusqu'à présent:

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

Cependant, cela montre toujours la ligne complète:

<td><a href="/path/to/file">Name of File</a></td> 

J'ai expérimenté plusieurs autres "méthodes" que j'ai trouvées sur divers sites Web, mais je continue à obtenir le même résultat.

Comment puis-je accéder aux groupes de capture nommés spécifiés dans mon expression régulière?

247
UnkwnTech

Utilisez la collection de groupes de l'objet Match en l'indexant avec le nom du groupe de capture, par exemple.

foreach (Match m in mc){
    MessageBox.Show(m.Groups["link"].Value);
}
256
Paolo Tedesco

Vous spécifiez la chaîne de groupe de capture nommée en la transmettant à l'indexeur de la propriété Groups d'un objet Match résultant.

Voici un petit exemple:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
        String sample = "hello-world-";
        Regex regex = new Regex("-(?<test>[^-]*)-");

        Match match = regex.Match(sample);

        if (match.Success)
        {
            Console.WriteLine(match.Groups["test"].Value);
        }
    }
}
107
Andrew Hare

L'exemple de code suivant correspond au modèle, même s'il y a des espaces. c'est à dire. :

<td><a href='/path/to/file'>Name of File</a></td>

aussi bien que:

<td> <a      href='/path/to/file' >Name of File</a>  </td>

La méthode retourne true ou false selon que la chaîne htmlTd en entrée correspond au modèle ou non. Si cela correspond, les paramètres out contiennent respectivement le lien et le nom.

/// <summary>
/// Assigns proper values to link and name, if the htmlId matches the pattern
/// </summary>
/// <returns>true if success, false otherwise</returns>
public static bool TryGetHrefDetails(string htmlTd, out string link, out string name)
{
    link = null;
    name = null;

    string pattern = "<td>\\s*<a\\s*href\\s*=\\s*(?:\"(?<link>[^\"]*)\"|(?<link>\\S+))\\s*>(?<name>.*)\\s*</a>\\s*</td>";

    if (Regex.IsMatch(htmlTd, pattern))
    {
        Regex r = new Regex(pattern,  RegexOptions.IgnoreCase | RegexOptions.Compiled);
        link = r.Match(htmlTd).Result("${link}");
        name = r.Match(htmlTd).Result("${name}");
        return true;
    }
    else
        return false;
}

J'ai testé cela et cela fonctionne correctement.

11
Rashmi Pandit

De plus, si quelqu'un a un cas d'utilisation où il a besoin de noms de groupe avant d'exécuter une recherche sur un objet Regex, il peut utiliser:

var regex = new Regex(pattern); // initialized somewhere
// ...
var groupNames = regex.GetGroupNames();
1
tinamou