7 votes

Regex .NET pour les caractères de la liste blanche

Considérons un algorithme qui a besoin de déterminer si un string contient des caractères en dehors de la liste des caractères autorisés.

La liste blanche ressemble à ceci :

'-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÖÜáíóúñÑÀÁÂÃÈÊËÌÍÎÏÐÒÓÔÕØÙÚÛÝßãðõøýþÿ

Remarque : les espaces et les apostrophes sont nécessaires pour être inclus dans cette liste blanche.

En général, il s'agit d'une méthode statique, mais elle sera convertie en méthode d'extension.

private bool ContainsAllWhitelistedCharacters(string input)
{
  string regExPattern="";// the whitelist
  return Regex.IsMatch(input, regExPattern);
}

Considérations :

Merci pour les commentaires sur la performance à tous ceux qui ont répondu. Les performances ne sont pas un problème. La qualité, la lisibilité et la maintenabilité le sont ! Moins de code = moins de risques de défauts, IMO.

Question :

Que doit être ce motif de regex de liste blanche ?

9voto

Mark Rushakoff Points 97350

Pourquoi faut-il que ce soit une regex ?

private bool ContainsAllWhitelistedCharacters(string input)
{
  string whitelist = "abcdefg...";
  foreach (char c in input) {
    if (whitelist.IndexOf(c) == -1)
      return false;
  }
  return true;
}

Il n'est pas nécessaire de se lancer directement dans les regex si vous n'êtes pas sûr de la façon d'implémenter celle dont vous avez besoin et si vous n'avez pas profilé cette section de code et découvert que vous avez besoin de performances supplémentaires.

5voto

Kelsey Points 26456

Vous pouvez utiliser la correspondance par motif en utilisant ce qui suit :

^([\-\.a-zA-Z ÇüéâäàåçêëèïîíìÄÅÉæÆôöòûùÖÜáíóúñÑÀÁÂÃÈÊËÌÍÎÏÐÒÓÔÕØÙÚÛÝßãðõøýþÿ]+)$

Faites-en une méthode d'extension avec :

public static bool IsValidCustom(this string value)
{
    string regExPattern="^([\-\.a-zA-Z ÇüéâäàåçêëèïîíìÄÅÉæÆôöòûùÖÜáíóúñÑÀÁÂÃÈÊËÌÍÎÏÐÒÓÔÕØÙÚÛÝßãðõøýþÿ]+)$";
    return Regex.IsMatch(input, regExPattern);
}

Je n'arrive pas à trouver un moyen facile de faire une gamme maintenable avec des caractères étendus puisque l'ordre des caractères n'est pas évident.

1voto

Mark Synowiec Points 3069

Je ne sais pas comment le backend regex est implémenté, mais il pourrait être plus efficace d'utiliser ce qui suit pour rechercher autre chose que votre liste :

private bool ContainsAllWhitelistedCharacters(string input)
{
   Regex r = new Regex("[^ your list of chars ]");
   return !r.IsMatch(test)
}

1voto

ShuggyCoUk Points 24204

Notez que je ne recommande pas cette méthode à moins que la performance soit vraiment un problème, mais j'ai pensé que je pourrais souligner que, même en incluant la précompilation de la regex, vous pouvez faire un peu plus vite :

comparer :

static readonly Regex r = new Regex(
  @"^(['\-\.a-zA-Z ÇüéâäàåçêëèïîíìÄÅÉæÆôöòûùÖÜáíóúñÑ"+
   "ÀÁÂÃÈÊËÌÍÎÏÐÒÓÔÕØÙÚÛÝßãðõøýþÿ]+)$");

public bool IsValidCustom(string value)
{
  return r.IsMatch(value);
}

avec :

private bool ContainsAllWhitelistedCharacters(string input)
{
    foreach (var c in input)
    {
        switch (c)
        {
            case '\u0020': continue; 
            case '\u0027': continue; 
            case '\u002D': continue; 
            case '\u002E': continue; 
            case '\u0041': continue; 
            case '\u0042': continue; 
            case '\u0043': continue; 
            case '\u0044': continue; 
            case '\u0045': continue; 
            case '\u0046': continue; 
            case '\u0047': continue; 
            case '\u0048': continue; 
            case '\u0049': continue; 
            case '\u004A': continue; 
            case '\u004B': continue; 
            case '\u004C': continue; 
            case '\u004D': continue; 
            case '\u004E': continue; 
            case '\u004F': continue; 
            case '\u0050': continue; 
            case '\u0051': continue; 
            case '\u0052': continue; 
            case '\u0053': continue; 
            case '\u0054': continue; 
            case '\u0055': continue; 
            case '\u0056': continue; 
            case '\u0057': continue; 
            case '\u0058': continue; 
            case '\u0059': continue; 
            case '\u005A': continue; 
            case '\u0061': continue; 
            case '\u0062': continue; 
            case '\u0063': continue; 
            case '\u0064': continue; 
            case '\u0065': continue; 
            case '\u0066': continue; 
            case '\u0067': continue; 
            case '\u0068': continue; 
            case '\u0069': continue; 
            case '\u006A': continue; 
            case '\u006B': continue; 
            case '\u006C': continue; 
            case '\u006D': continue; 
            case '\u006E': continue; 
            case '\u006F': continue; 
            case '\u0070': continue; 
            case '\u0071': continue; 
            case '\u0072': continue; 
            case '\u0073': continue; 
            case '\u0074': continue; 
            case '\u0075': continue; 
            case '\u0076': continue; 
            case '\u0077': continue; 
            case '\u0078': continue; 
            case '\u0079': continue; 
            case '\u007A': continue; 
            case '\u00C0': continue; 
            case '\u00C1': continue; 
            case '\u00C2': continue; 
            case '\u00C3': continue; 
            case '\u00C4': continue; 
            case '\u00C5': continue; 
            case '\u00C6': continue; 
            case '\u00C7': continue; 
            case '\u00C8': continue; 
            case '\u00C9': continue; 
            case '\u00CA': continue; 
            case '\u00CB': continue; 
            case '\u00CC': continue; 
            case '\u00CD': continue; 
            case '\u00CE': continue; 
            case '\u00CF': continue; 
            case '\u00D0': continue; 
            case '\u00D1': continue; 
            case '\u00D2': continue; 
            case '\u00D3': continue; 
            case '\u00D4': continue; 
            case '\u00D5': continue; 
            case '\u00D6': continue; 
            case '\u00D8': continue; 
            case '\u00D9': continue; 
            case '\u00DA': continue; 
            case '\u00DB': continue; 
            case '\u00DC': continue; 
            case '\u00DD': continue; 
            case '\u00DF': continue; 
            case '\u00E0': continue; 
            case '\u00E1': continue; 
            case '\u00E2': continue; 
            case '\u00E3': continue; 
            case '\u00E4': continue; 
            case '\u00E5': continue; 
            case '\u00E6': continue; 
            case '\u00E7': continue; 
            case '\u00E8': continue; 
            case '\u00E9': continue; 
            case '\u00EA': continue; 
            case '\u00EB': continue; 
            case '\u00EC': continue; 
            case '\u00ED': continue; 
            case '\u00EE': continue; 
            case '\u00EF': continue; 
            case '\u00F0': continue; 
            case '\u00F1': continue; 
            case '\u00F2': continue; 
            case '\u00F3': continue; 
            case '\u00F4': continue; 
            case '\u00F5': continue; 
            case '\u00F6': continue; 
            case '\u00F8': continue; 
            case '\u00F9': continue; 
            case '\u00FA': continue; 
            case '\u00FB': continue; 
            case '\u00FC': continue; 
            case '\u00FD': continue; 
            case '\u00FE': continue; 
            case '\u00FF': continue;        
        }
        return false;     
    }    return true; // empty string is true    
}

Lors d'un test très rapide sur un corpus de mots avec un taux de réussite d'environ 60%, j'ai obtenu une accélération d'environ un facteur 8 avec cette approche.

Ce n'est pas non plus beaucoup moins lisible que la regex sans les caractères d'échappement !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X