web-dev-qa-db-fra.com

Expressions régulières C # - est-il possible d'extraire des correspondances lors de la correspondance?

Disons que j'ai une chaîne dont j'ai besoin pour vérifier le format correct; par exemple. RR1234566-001 (2 lettres, 7 chiffres, tiret, 1 ou plusieurs chiffres). J'utilise quelque chose comme:

        Regex regex = new Regex(patternString);
        if (regex.IsMatch(stringToMatch))
        {
            return true;
        }
        else
        {
            return false;
        }

Cela fonctionne pour me dire si le stringToMatch suit le modèle défini par patternString. Ce dont j'ai besoin (et je finis par les extraire plus tard) sont: 123456 et 001 - c'est-à-dire des portions de stringToMatch.

Veuillez noter que ce n'est PAS une question sur la façon de construire des expressions régulières. Ce que je demande, c'est: "Y a-t-il un moyen de faire correspondre et d'extraire des valeurs simultanément sans avoir à utiliser une fonction de fractionnement plus tard?"

25
sarsnake

Vous pouvez utiliser des groupes d'expression régulière pour ce faire. Par exemple, cette regex:

(\d\d\d)-(\d\d\d\d\d\d\d)

Associons un numéro de téléphone à cette expression régulière:

var regex = new Regex(@"(\d\d\d)-(\d\d\d\d\d\d\d)");
var match = regex.Match("123-4567890");
if (match.Success)
    ....

S'il correspond, vous trouverez les trois premiers chiffres dans:

match.Groups[1].Value

Et les 7 chiffres suivants:

match.Groups[2].Value

P.S. En C #, vous pouvez utiliser une chaîne de style @ "" pour éviter d'échapper des contre-obliques. Par exemple, @ "\ hi \" est égal à "\\ hi \\". Utile pour les expressions régulières et les chemins.

P.S.2. Le premier groupe est stocké dans le groupe [1], pas dans le groupe [0] comme vous vous en doutez. C'est parce que le groupe [0] contient toute la chaîne correspondante.

67
Andomar

Utilisez plutôt le regroupement et les correspondances.

C'est à dire.:

// NOTE: pseudocode.
Regex re = new Regex("(\\d+)-(\\d+)");
Match m = re.Match(stringToMatch))

if (m.Success) {
  String part1 = m.Groups[1].Value;
  String part2 = m.Groups[2].Value;
  return true;
} 
else {
  return false;
}

Vous pouvez également nommer les correspondances, comme ceci:

Regex re = new Regex("(?<Part1>\\d+)-(?<Part2>\\d+)");

et accéder comme ça

  String part1 = m.Groups["Part1"].Value;
  String part2 = m.Groups["Part2"].Value;
17
cyberconte

Vous pouvez utiliser des parenthèses pour capturer des groupes de caractères:

string test = "RR1234566-001";

// capture 2 letters, then 7 digits, then a hyphen, then 1 or more digits
string rx = @"^([A-Za-z]{2})(\d{7})(\-)(\d+)$";

Match m = Regex.Match(test, rx, RegexOptions.IgnoreCase);

if (m.Success)
{
    Console.WriteLine(m.Groups[1].Value);    // RR
    Console.WriteLine(m.Groups[2].Value);    // 1234566
    Console.WriteLine(m.Groups[3].Value);    // -
    Console.WriteLine(m.Groups[4].Value);    // 001
    return true;
}
else
{
    return false;
}
13
LukeH