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;
}
}
}