189 8069 5689

使用正则表达式实现像SQL中LIKE语句中的%和_通配-创新互联

在项目中我们经常遇到将数据库的数据取到后再次进行筛选过滤的情况。LINQ to Entity提供了统一的查询接口并且可以高效的完成工作,但是对于我们常在SQL中使用的%和_这样的通配符并没有支持。我们只能通过String.Contains方法来实现简单的通配。使用String.Contains方法是无法达到在查询串中使用通配符的目的的。正则表达式虽然晦涩难懂,但功能十分强大,解决个统配符绰绰有余。

10年积累的网站设计、成都做网站经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先建设网站后付款的网站建设流程,更有府谷免费网站建设让你可以放心的选择与我们合作。

代码如下:

    public static class LINQHelper
    {
        /// 
        /// The all regex meta chars
        /// 
        private static string[] REGEX_META_CHARS = { "\\", ".", "^", "$", "*", "+", "?", "{", "}", "(", ")", "[", "]" };

        /// 
        /// Like method work as SQL like
        /// 
        /// The search string
        /// The SQL pattern
        /// Whether match or not
        public static bool Like(this string searchString, string sqlPattern)
        {
            if (searchString == null)
            {
                return false;
            }
            else
            {
                string convertedPattern = EscapeRegexMetaChars(sqlPattern).Replace("_", ".").Replace("%", ".*");
                convertedPattern = String.Format("^{0}$", convertedPattern);

                return Regex.IsMatch(searchString, convertedPattern, RegexOptions.Singleline);
            }
        }

        /// 
        /// Like method work as SQL like
        /// 
        /// The search string
        /// The SQL pattern
        /// The escape char
        /// Whether match or not
        public static bool Like(this string searchString, string sqlPattern, char escapeChar)
        {
            if (searchString == null)
            {
                return false;
            }
            else
            {
                string convertedPattern = EscapeRegexMetaChars(sqlPattern);
                convertedPattern = ReplaceWildcards(convertedPattern, '_', ".", escapeChar);
                convertedPattern = ReplaceWildcards(convertedPattern, '%', ".*", escapeChar);
                convertedPattern = String.Format("^{0}$", convertedPattern);

                return Regex.IsMatch(searchString, convertedPattern, RegexOptions.Singleline);
            }
        }

        /// 
        /// Replace wildcards
        /// 
        /// The replacement string
        /// The wildcard
        /// The replace wild char to
        /// The escape char
        /// The converted search value
        private static string ReplaceWildcards(string replacement, char wildcard, string replaceTo, char escapeChar)
        {
            string regexExpression = String.Format("(^|[^{0}])({1}+)", escapeChar, wildcard);
            return Regex.Replace(replacement, regexExpression, match => String.Format("{0}{1}", match.Groups[1].Value, match.Groups[2].Value.Replace(wildcard.ToString(), replaceTo)))
                .Replace(string.Format("{0}{1}", escapeChar, wildcard), wildcard.ToString());
        }

        /// 
        /// Escape regex meta chars
        /// 
        /// The replacement string
        /// The converted search value
        private static string EscapeRegexMetaChars(string replacement)
        {
            string resultString = replacement;
            foreach (string metaChar in REGEX_META_CHARS)
            {
                resultString = resultString.Replace(metaChar, string.Format(@"\{0}", metaChar));
            }

            return resultString;
        }
    }

首先,要将查询串中所有正则表达式的元字符转义为普通字符,这样才能安全的使用正则表达式进行匹配。

然后,将”_”和”%”替换成相应的正则表达式,即”_”替换成”.”,”%”替换成”.*”。这里还考虑到SQL的LIKE语句也有转义符功能,即如果使用ESCAPE子句则LIKE串中转义符后的”_”和”%”变为普通字符而不是通配符。所以当使用转义符时处理如下:

  • 将所有不以转义符引导的通配符替换。

  • 再将转义符引导的通配符的转义符去掉,即将通配符转义为普通字符。

以下是几个转换的例子:

  • LIKE ‘A_B’ 转换为 A.B

  • LIKE ‘A%B’ 转换为 A.*B

  • LIKE ‘A~_B’ ESCAPE ‘~’ 转换为 A_B

  • LIKE ‘A.B’ 转换为 A/.B

优点:我们可以在LINQ语句的条件中方便的使用Like方法去过滤数据,LINQ语句整体上会保持很好的可读性。

缺点:Like 方法会被调用n次(n取决于数据量),解析SQL pattern到正则表达式pattern的代码就要被重复执行n次。因此当数据量过大时解析pattern会消耗一定的资源。当然这可以通过一些方法去解决,如缓存解析结果,或改为传入就是解析好的正则表达式等。

创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


名称栏目:使用正则表达式实现像SQL中LIKE语句中的%和_通配-创新互联
网页URL:http://cdxtjz.cn/article/dgdodi.html

其他资讯