using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using AutoCheckSMS.Common; namespace AutoCheckSMS { /// /// 匹配模型 /// public class Match { private static Match _instance; public static Match Instance { get { if (_instance == null) { _instance = new Match(); } return _instance; } } /// /// 正则匹配 /// /// public bool IsMatchByRegular(List _Templates,string _Content) { List list = _Templates.FindAll(c=>c.MatchType==1);//1表示正则匹配方式 if (list.Count <= 0) return false; foreach (A_template template in list) { try { Regex regex = new Regex(template.Template); if (regex.IsMatch(_Content)) { return true; } } catch(Exception ex) { Log4netService.Error($"异常:{ex.Message}"); } } return false; } /// /// 通配符匹配 /// /// /// /// public bool IsMatchByWildcard(List _Templates, string _Content) { List list = _Templates.FindAll(c => c.MatchType == 0);//1表示正则匹配方式 if (list.Count <= 0) return false; foreach(A_template _Template in list) { try { if (Greedy(_Content, _Template.Template)) { return true; } } catch (Exception ex) { Log4netService.Error($"匹配异常:{ex.Message}"); } } return false; } /// /// 贪心算法 /// /// 字符串 /// 给定模式字符串 /// private bool Greedy(string s, string p) { int sRight = s.Length, pRight = p.Length; //模式p的结尾不是*号,为?或字符,则与s的结尾一个个判断是否匹配 while (sRight > 0 && pRight > 0 && p.Substring(pRight - 1,1) != "*") { if (CharMatch(s.Substring(sRight - 1,1), p.Substring(pRight - 1,1))) { --sRight; --pRight; } else { //只要结尾有一个非*字符不能匹配s对应位置字符就返回false return false; } } //p为空模式 if (pRight == 0) { //s为空串则匹配,否则不匹配 return sRight == 0; } int sIndex = 0, pIndex = 0; int sRecord = -1, pRecord = -1; while (sIndex < sRight && pIndex < pRight) { //出现 * 假设其不匹配任何字符,继续判断剩下的 s 和 p 是否匹配 //并记录该 * 号下一个字符的下标,和对应的 s 的下标,便于(后悔)即不匹配的时候,返回来让 * 匹配部分 s 中的字符看剩下的是否匹配 if (p.Substring(pIndex,1) == "*") { ++pIndex; sRecord = sIndex; pRecord = pIndex; //s[sIndex]和p[pIndex]匹配,则指针后移,判断剩下的是否匹配 } else if (CharMatch(s.Substring(sIndex,1), p.Substring(pIndex,1))) { ++sIndex; ++pIndex; // 出现了 * 号,且 * 不起作用时(即不匹配任何字符串时),s 和 p 不匹配则倒退回来(后悔), // 让 * 代表部分 s 的字符串,继续判断剩下的是否匹配 } else if (sRecord != -1 && sRecord + 1 < sRight) { ++sRecord; sIndex = sRecord; pIndex = pRecord; } else { return false; } } return AllStars(p, pIndex, pRight); } //判断;两个字符是否匹配 private bool CharMatch(string u, string v) { return u == v || v == "?"; } //若 p 的左边一部分已经完全匹配了 s ,则此时 pIndex < pRight, p 剩下的p(pIndex)到p(pRight) 部分必须全为*,才匹配 //不然 s 不存在对应的字符串片段与 p 该段的字符相匹配,所以返回false //如果最后pIndex==pRight则返回true,是匹配的 private bool AllStars(string str, int left, int right) { for (int i = left; i < right; ++i) { if (str.Substring(i,1) != "*") { return false; } } return true; } } }