11using System ;
22using System . Collections . Generic ;
3+ using System . Text . RegularExpressions ;
34
45namespace Ardalis . Specification ;
56
@@ -11,16 +12,34 @@ public static bool Like(this string input, string pattern)
1112 {
1213 return SqlLike ( input , pattern ) ;
1314 }
14- catch ( Exception )
15+ catch ( Exception ex )
1516 {
16- throw new InvalidSearchPatternException ( pattern ) ;
17+ throw new InvalidSearchPatternException ( pattern , ex ) ;
1718 }
1819 }
1920
21+ private static bool SqlLike ( this string input , string pattern )
22+ {
23+ // Escape special regex characters, excluding those handled separately
24+ var regexPattern = Regex . Escape ( pattern )
25+ . Replace ( "%" , ".*" ) // Translate SQL LIKE wildcard '%' to regex '.*'
26+ . Replace ( "_" , "." ) // Translate SQL LIKE wildcard '_' to regex '.'
27+ . Replace ( @"\[" , "[" ) // Unescape '[' as it's used for character classes/ranges
28+ . Replace ( @"\^" , "^" ) ; // Unescape '^' as it can be used for negation in character classes
29+
30+ // Ensure the pattern matches the entire string
31+ regexPattern = "^" + regexPattern + "$" ;
32+ var regex = new Regex ( regexPattern , RegexOptions . IgnoreCase ) ;
33+
34+ return regex . IsMatch ( input ) ;
35+ }
36+
2037 // This C# implementation of SQL Like operator is based on the following SO post https://stackoverflow.com/a/8583383/10577116
2138 // It covers almost all of the scenarios, and it's faster than regex based implementations.
2239 // It may fail/throw in some very specific and edge cases, hence, wrap it in try/catch.
23- private static bool SqlLike ( string str , string pattern )
40+ // UPDATE: it returns incorrect results for some obvious cases.
41+ // More details in this issue https://github.com/ardalis/Specification/issues/390
42+ private static bool SqlLikeOption2 ( string str , string pattern )
2443 {
2544 var isMatch = true ;
2645 var isWildCardOn = false ;
0 commit comments