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
