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
|
{
|
/// <summary>
|
/// 匹配模型
|
/// </summary>
|
public class Match
|
{
|
private static Match _instance;
|
public static Match Instance {
|
get {
|
if (_instance == null)
|
{
|
_instance = new Match();
|
}
|
return _instance;
|
}
|
}
|
|
|
|
/// <summary>
|
/// 正则匹配
|
/// </summary>
|
/// <returns></returns>
|
public bool IsMatchByRegular(List<A_template> _Templates,string _Content)
|
{
|
List<A_template> 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;
|
}
|
|
|
/// <summary>
|
/// 通配符匹配
|
/// </summary>
|
/// <param name="_Templates"></param>
|
/// <param name="_Content"></param>
|
/// <returns></returns>
|
public bool IsMatchByWildcard(List<A_template> _Templates, string _Content)
|
{
|
List<A_template> 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;
|
}
|
|
/// <summary>
|
/// 贪心算法
|
/// </summary>
|
/// <param name="s">字符串</param>
|
/// <param name="p">给定模式字符串</param>
|
/// <returns></returns>
|
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;
|
}
|
|
}
|
}
|