2222// </copyright>
2323// ----------------------------------------------------------------------------------
2424
25+ using System . Text ;
26+
2527namespace NMemory
2628{
2729 using System . Text . RegularExpressions ;
@@ -30,20 +32,42 @@ public static class Functions
3032 {
3133 public static bool Like ( string input , string pattern )
3234 {
33- // http://stackoverflow.com/questions/5663655/like-operator-in-linq-to-objects
35+ // https://stackoverflow.com/a/5663768/5619143
36+
37+ var regex = new Regex ( ConvertLikeToRegex ( pattern ) , RegexOptions . IgnoreCase ) ;
38+ return IsRegexMatch ( input , regex ) ;
39+ }
40+
41+ internal static bool IsRegexMatch ( string input , Regex regex )
42+ {
43+ if ( input == null )
44+ return false ;
45+
46+ return regex . IsMatch ( input ) ;
47+ }
48+
49+ internal static string ConvertLikeToRegex ( string pattern )
50+ {
51+ StringBuilder builder = new StringBuilder ( ) ;
52+ // Turn "off" all regular expression related syntax in the pattern string
53+ // and add regex begining of and end of line tokens so '%abc' and 'abc%' work as expected
54+ builder . Append ( "^" ) . Append ( Regex . Escape ( pattern ) ) . Append ( "$" ) ;
3455
35- // Turn "off" all regular expression related syntax in the pattern string.
36- pattern = Regex . Escape ( pattern ) ;
56+ /* Replace the SQL LIKE wildcard metacharacters with the
57+ * equivalent regular expression metacharacters. */
58+ builder . Replace ( "%" , ".*" ) . Replace ( "_" , "." ) ;
3759
38- // Replace the SQL LIKE wildcard metacharacters with the equivalent regular expression metacharacters.
39- pattern = pattern . Replace ( "%" , ".*?" ) . Replace ( "_" , "." ) ;
60+ /* The previous call to Regex.Escape actually turned off
61+ * too many metacharacters, i.e. those which are recognized by
62+ * both the regular expression engine and the SQL LIKE
63+ * statement ([...] and [^...]). Those metacharacters have
64+ * to be manually unescaped here. */
65+ builder . Replace ( @"\[" , "[" ) . Replace ( @"\]" , "]" ) . Replace ( @"\^" , "^" ) ;
4066
41- // The previous call to Regex.Escape actually turned off too many metacharacters, i.e. those which
42- // are recognized by both the regular expression engine and the SQL LIKE statement ([...] and [^...]).
43- // Those metacharacters have to be manually unescaped here.
44- pattern = pattern . Replace ( @"\[" , "[" ) . Replace ( @"\]" , "]" ) . Replace ( @"\^" , "^" ) ;
67+ // put SQL LIKE wildcard literals back
68+ builder . Replace ( "[.*]" , "[%]" ) . Replace ( "[.]" , "[_]" ) ;
4569
46- return Regex . IsMatch ( input , pattern , RegexOptions . IgnoreCase ) ;
70+ return builder . ToString ( ) ;
4771 }
4872 }
4973}
0 commit comments