Avec l'expression régulière suivante:
\s*,\s*(\w*)
et la chaîne de test:
Full match: InitValue(Input1, Input2, ..., Inputn) Group1: Input1 Group2: Input2 .... Groupn: Inputn
j'obtiens le résultat suivant:
Full match: InitValue(Input1, Input2) Group1: Input1 Group2: Input2
Avec l'expression régulière suivante:
InitValue(Input1, Input2)
et la chaîne de test:
InitValue\((\w*)\s*,\s*(\w*)\)
J'obtiens:
Full match: InitValue(Input1) Group1: Input1
Maintenant, je voudrais capturer n'importe quel nombre d'arguments de la méthode InitValue. Le nombre d'arguments de InitValue est inconnu.
InitValue(Input1)
Bien sûr, je ne peux pas répéter le modèle suivant dans mon expression régulière car je ne connais pas le nombre d'arguments à l'avance:
InitValue\((\w*)\)
Comment écrire une expression régulière qui génère n nombre de groupes de capture?
J'utilise l'expression régulière en C # -code (Regex, Match) ...
4 Réponses :
Ne laissez personne vous dire ce que c'est impossible et ce que ce n'est pas
Vous devrez le toucher un peu mais je pense qu'il peut vous guider = D.
Modifier, en répondant à votre question. b.Count
vous donnera le nombre de correspondances.
Edit 2, je poste l'image pour afficher les informations de débogage. Mais voici le code pour le sibariste.
string input = "InitValue(test, othertest, bleh, blehTest, foo)"; Regex regArgs = new Regex(@"(?:InitValue\()(.*)(?:\))"); Match matchArgs = regArgs.Match(input); string valueArgs = matchArgs.Groups[1].Value; Regex reg = new Regex(@"[\w]+"); MatchCollection b = reg.Matches(valueArgs); string b1 = b[0].Value; string b2 = b[1].Value; int numberGroups = b.Count;
Edit 3, comme suggéré dans le commentaire c'est la solution complète, vous devrez effacer le Partie InitValue (*) avec un autre Regex
ou avec une Substring
string bar = "test, othertest"; Regex reg = new Regex(@"[\w]+"); MatchCollection b = reg.Matches(bar); string b1 = b[0].Value; string b2 = b[1].Value; int numberGroups = b.Count;
Veuillez montrer comment appliquer cette technique à la chaîne de test: InitValue (Input1, Input2, Input3, Input4)
Que voulez-vous dire? Comme je l'ai dit, ce n'est qu'une illustration, pas la solution complète, mais assez proche. Vous pouvez facilement supprimer la InitValue (*)
avec une Substring
et conserver les arguments, si vous voulez dire que c'est impossible quand c'est écrit InitValue, alors oui, vous avez raison, mais c'est loin d'être impossible = D
Il est possible de le faire dans .NET - vous utilisez un seul Groupe
de capture, puis vous accédez à la collection Captures
du groupe pour voir tous les éléments capturés, pas seulement la valeur
finale.
Vous devrez écrire une expression régulière qui peut répéter le groupe de correspondance d'arguments, quelque chose comme
InitValue\((?:(\w+)\s*(?:,(?!\s*\))|(?=\s*\)))\s*)*\)
Jouez avec la Démo Debuggex pour qu'elle corresponde à ce que vous voulez. P >
static void GetParams() { int x = 0; var strings = new[] { "InitValue()", "InitValue(Input1)", "InitValue(Input1, Input2, Input3, Input4)" }; var pattern = @"(\w+)\((?:(\w+)(?:,?\s*))*\)"; foreach (var s in strings) { WriteLine($"String: '{s}'"); var match = Regex.Match(s, pattern); if (match.Success) { WriteLine($"\tMethod: '{match.Groups[1].Value}'"); WriteLine("\tParameters:"); var captures = match.Groups[2].Captures; if (captures.Count > 0) { x = 0; foreach (Capture capture in captures) { WriteLine($"\t\tParam {++x}: '{capture.Value}'"); } } else { WriteLine("\t\tNo params found."); } WriteLine(); } else WriteLine("No matches found."); } } /* Output: String: 'InitValue()' Method: 'InitValue' Parameters: No params found. String: 'InitValue(Input1)' Method: 'InitValue' Parameters: Param 1: 'Input1' String: 'InitValue(Input1, Input2, Input3, Input4)' Method: 'InitValue' Parameters: Param 1: 'Input1' Param 2: 'Input2' Param 3: 'Input3' Param 4: 'Input4' */
.NET prend en charge la recherche infinie derrière Explication Par exemple: Résultat Voir le Démo Regex | Démo C # (? . Au lieu d'obtenir des groupes de capture, une autre option pourrait être d'obtenir les correspondances à la place:
Input1
Input2
Input3
(? Lookbehind positif, vérifiez ce qui est sur la gauche correspond:
\ bInitValue \ ([^ ()] *
Correspondre au wordboundary, InitValue (
puis 0+ fois aucun des (
ou ) )
Fermer la recherche positive [^, \ t] +
Classe de caractères négatifs, correspond à plus de 1 fois sans espace ni virgule (? =
Recherche positive pour vérifier ce qu'il y a sur les bonnes correspondances:
[^ ()] * \)
Correspond à 0 fois ou plus aucun des (
ou )
, puis correspond à )
)
Fermer la recherche positive string pattern = @"(?<=\bInitValue\([^()]*)[^, ]+(?=[^()]*\))";
string str = "InitValue(Input1, Input2, Input3)";
foreach (Match m in Regex.Matches(str, pattern))
{
Console.WriteLine(m.Value);
}
(?<=\bInitValue\([^()]*)[^, ]+(?=[^()]*\))