2008-09-05 18 views

Respuesta

7

La siguiente expresión regular convierte una SQL como patrón en un patrón de expresión regular con la ayuda de un delegado MatchEvaluator. Maneja correctamente los bloques de corchetes cuadrados y escapa de los caracteres Regex especiales.

string regexPattern = Regex.Replace(
    likePattern, 
    @"[%_]|\[[^]]*\]|[^%_[]+", 
    match => 
    { 
     if (match.Value == "%") 
     { 
      return ".*"; 
     } 
     if (match.Value == "_") 
     { 
      return "."; 
     } 
     if (match.Value.StartsWith("[") && match.Value.EndsWith("]")) 
     { 
      return match.Value; 
     } 
     return Regex.Escape(match.Value); 
    }); 
-1

Encontré un módulo Perl llamado Regexp::Wildcards. Puede tratar de portarlo o probar Perl.NET. Tengo la sensación de que también puedes escribir algo tú mismo.

2

Desde el ejemplo anterior, me gusta este atacarlo (hablo en términos generales, porque no sé C#):

romperlo por COMO '...', puso el . .. piezas en una matriz. Reemplazar sin escape % signos por . *, pone de relieve por., Y en este caso la [C-P] arsen se traduce directamente en expresión regular.

Vuelva a unir las piezas de la matriz con una tubería y ajuste el resultado entre paréntesis y los bits de expresiones regulares estándar.

El resultado sería:

/^(.*this.*|Sm.th|[C-P]arsen)$/ 

Lo más importante aquí es que tener cuidado de todas las maneras en que puede escapar de datos y que se traducen en comodines que las expresiones regulares.

% becomes .* 
_ becomes . 
+0

Una cosa a tener en cuenta, es que si el patrón sql like contiene \, entonces quiere escapar de eso en la expresión regular. Regex.Escape ayudaría aquí – mrwaim

3

Además de @ solución de Nathan-Baulch puedes usar el siguiente código para manejar también el caso en que un carácter de escape costumbre se ha definido utilizando la sintaxis LIKE '!%' ESCAPE '!'.

public Regex ConvertSqlLikeToDotNetRegex(string regex, char? likeEscape = null) 
    { 
     var pattern = string.Format(@" 
      {0}[%_]| 
      [%_]| 
      \[[^]]*\]| 
      [^%_[{0}]+ 
      ", likeEscape); 

     var regexPattern = Regex.Replace(
      regex, 
      pattern, 
      ConvertWildcardsAndEscapedCharacters, 
      RegexOptions.IgnorePatternWhitespace); 

     regexPattern = "^" + regexPattern + "$"; 

     return new Regex(regexPattern, 
      !m_CaseSensitive ? RegexOptions.IgnoreCase : RegexOptions.None); 
    } 

    private string ConvertWildcardsAndEscapedCharacters(Match match) 
    { 
     // Wildcards 
     switch (match.Value) 
     { 
      case "%": 
       return ".*"; 
      case "_": 
       return "."; 
     } 

     // Remove SQL defined escape characters from C# regex 
     if (StartsWithEscapeCharacter(match.Value, likeEscape)) 
     { 
      return match.Value.Remove(0, 1); 
     } 

     // Pass anything contained in []s straight through 
     // (These have the same behaviour in SQL LIKE Regex and C# Regex) 
     if (StartsAndEndsWithSquareBrackets(match.Value)) 
     { 
      return match.Value; 
     } 

     return Regex.Escape(match.Value); 
    } 

    private static bool StartsAndEndsWithSquareBrackets(string text) 
    { 
     return text.StartsWith("[", StringComparison.Ordinal) && 
       text.EndsWith("]", StringComparison.Ordinal); 
    } 

    private bool StartsWithEscapeCharacter(string text, char? likeEscape) 
    { 
     return (likeEscape != null) && 
       text.StartsWith(likeEscape.ToString(), StringComparison.Ordinal); 
    } 
Cuestiones relacionadas