web-dev-qa-db-fra.com

Caractère générique d'expression régulière

Je viens juste de commencer à utiliser Regular Expressions et c'est tellement accablant que, même après avoir lu la documentation, je ne trouve pas par où commencer pour aider à résoudre mon problème.

Je dois un tas de chaînes. 

 "Project1 - Notepad"
 "Project2 - Notepad"
 "Project3 - Notepad"
 "Untitled - Notepad"
 "HeyHo - Notepad"

Et j'ai une chaîne contenant un joker.

"* - Notepad"

J'aurais besoin de cela si je compare l'une de ces chaînes à celle contenant le caractère générique, elle retourne vrai. (Avec Regex.IsMatch() ou quelque chose comme ça ..) 

Habituellement, je ne demande pas de réponses comme ça mais je ne trouve pas ce dont j'ai besoin. Quelqu'un pourrait-il me signaler dans la bonne direction? 

11
phadaphunk

Le caractère générique * est équivalent au motif Regex ".*" (gourmand) ou ".*?" (non-gourmand), vous voudrez donc effectuer une string.Replace():

string pattern = Regex.Escape(inputPattern).Replace("\\*", ".*?");

Notez la Regex.Escape(inputPattern) au début. Puisque inputPattern peut contenir des caractères spéciaux utilisés par Regex, vous devez les échapper correctement. Si vous ne le faites pas, votre modèle exploserait.

Regex.IsMatch(input, ".NET"); // may match ".NET", "aNET", "FNET", "7NET" and many more

Par conséquent, le caractère générique * est échappé à \\*, raison pour laquelle nous remplaçons le caractère générique échappé plutôt que simplement le caractère générique lui-même.


Pour utiliser le motif

vous pouvez faire soit:

Regex.IsMatch(input, pattern);

ou

var regex = new Regex(pattern);
regex.IsMatch(input);

Différence entre gourmand et non-gourmand

La différence réside dans la mesure dans laquelle le motif essayera de correspondre.

Considérez la chaîne suivante: "hello (x+1)(x-1) world". Vous voulez faire correspondre le crochet d'ouverture ( et le crochet de fermeture ) ainsi que tout ce qui se trouve entre les deux.

Greedy ne correspond qu'à "(x+1)(x-1)" et à rien d'autre. Elle correspond fondamentalement à la plus longue sous-chaîne à laquelle elle peut correspondre.

Non-gourmand correspondrait à "(x+1)" and (x-1) et à rien d'autre. En d'autres termes: les sous-chaînes les plus courtes possibles.

15
Nolonar

Je viens d'écrire ceci rapidement (basé sur Valider qu'une chaîne contient des mots exacts )

    static void Main()
    {
        string[] inputs = 
        {
            "Project1 - Notepad", // True
            "Project2 - Notepad", // True
            "HeyHo - Notepad", // True
            "Nope - Won't work" // False
        };

        const string filterParam = "Notepad";
        var pattern = string.Format(@"^(?=.*\b - {0}\b).+$", filterParam);

        foreach (var input in inputs)
        {
            Console.WriteLine(Regex.IsMatch(input, pattern));
        }
        Console.ReadLine();
    }
5

Vous devriez faire comme ça:

string myPattern = "* - Notepad";
foreach(string currentString in myListOfString)
    if(Regex.IsMatch(currentString, myPattern, RegexOptions.Singleline){
        Console.WriteLine("Found : "+currentString);
    }
}

En passant, je vous ai vu venir de Montréal, documentation française supplémentaire + outil utile: http://www.olivettom.com/?p=84

Bonne chance!

3
Thomas

On dirait que le motif souhaité est le suivant:

/^.+-\s*Notepad$/

Ce modèle correspond à une chaîne entière s'il se termine par "- Bloc-notes".

1
Daedalus