www.bewise.fr

Recherche

Regex : Refuser une chaine de caractères

Par L'équipe Bewise, posté le 12/07/2010

Tags : C#

Les expressions régulières c'est très bien, mais il y a un gros manque dans la syntaxe : il n'existe pas de façon simple de chercher une expressions qui ne contient PAS une certaine chaîne de caractères.

Si on veut refuser un seul caractère 'a', on fait un :

[^a]*

Mais si on veut refuser la chaîne « ab », il faut :

- Prendre tous les caractères différents de 'a'

- Prendre tous les caractères 'a' non suivis d'un caractère 'b'

Ce qui nous donne :

([^a]|a[^b])*

[Attention, le caractère ^ signifie « tout sauf », mais uniquement dans une énumération de caractère (ie : entre crochets). Il s'applique à chaque caractère séparément et non à une chaîne.

Utilisé en dehors de crochets, il représente un début de ligne.]

Cette écriture peut vite devenir très lourde si on a une chaîne un peu longue.

Alors j'ai fait une petite fonction qui à partir d'une chaîne de caractère quelconque renvoie l'expression régulière qui représente « tout sauf cette chaîne »

public string regexRefuseString(string chaine, bool ignoreCase)
{
    String regex = String.Empty;
    String oldCharRefused = String.Empty;
    foreach (char c in chaine)
    {
        if (!String.IsNullOrEmpty(regex))
        {
            regex += "|";
        }
        if (!String.IsNullOrEmpty(oldCharRefused))
        {
            regex += oldCharRefused;
        }
        if (ignoreCase && char.ToUpper(c) != char.ToLower(c))
        {
            oldCharRefused += String.Format("[{0}{1}]", char.ToUpper(c), char.ToLower(c));
            regex += String.Format("[^{0}{1}]", char.ToUpper(c), char.ToLower(c));
        }
        else
        {
            oldCharRefused += c;
            regex += String.Format("[^{0}]", c);
        }
    }
    return String.Format("({0})*", regex);
}

Le paramètre ignoreCase permet lorsqu'il est vrai de faire une recherche ignorant la casse (vous ne l'auriez pas deviné je suis sûr).

Ce qui nous donnera :

regexRefuseString("ab", false)

-> ([^a]|a[^b])*

regexRefuseString("ab", true)

-> ([^Aa]|[Aa][^Bb])*

Par contre si vous l'utilisez faites attention, cette fonction ne prend aucunement en compte les caractères spéciaux


Commentaires