阅前须知
- C# ,此篇主要讲讲逻辑,逻辑学会,其他语音都是一样的;
- DataTable ,DataTable是 ADO.NET 库中的中心对象。;
实际项目需求分析
在做项目时,我们会在数据库中某一张表中存入一个字段,这个字段主要是存入一个逻辑表达式,我们需要把这个字符串的逻辑表达式取出来通过判断后进行后面的操作,在这里我们发现如果使用简单的DataTable是判断不了复杂的逻辑表达式,比如7>2&&(4<7||8>4)这种有括号的,所以需要写一个通用的方法进行判断。
逻辑梳理
- 首先判断有无括号,如果有先判断里面的,如果使用字符串的替换,把结果替换上去
- 没有括号的逻辑表达式,通过拆分’||‘或’&&‘,在进行判断
- 写一个字符串匹配的方法,匹配’||‘和’&&‘来进行判断
开发
第一步,需要创建一个匹配’||‘和’&&‘的方法进行判断
很简单的方法,通过字符串re来决定判断a1和a2的逻辑后的结果
public Boolean LogicEx(Boolean a1,Boolean a2,string re)
{
Boolean result = false;
switch (re)
{
case "&&":result = a1 && a2;break;
case "||":result = a1 || a2;break;
}
return result;
}
第二步,需要创建一个没有括号的逻辑表达式
主要用于判断没有括号的逻辑表达式比如:4>2&&5>3&&9>3
这个方法主要是logicStr来决定两两比较的方式,调用上面的方法得到结果,然后一直重复到结束
/// <summary>
/// 判读逻辑表达式
/// </summary>
/// <param name="str">需要判断的逻辑表达式字符串</param>
/// <returns></returns>
public Boolean LogicExpression(string str)
{
Boolean result = false;
DataTable dt = new DataTable();
string[] logicExData = Regex.Split(str, @"\|\||&&", RegexOptions.IgnoreCase);
string logicStr = "||";
for(int logicExIndex = 0; logicExIndex < logicExData.Length; logicExIndex++)
{
if (logicExIndex != 0)
{
logicStr = str.Substring(str.IndexOf(logicExData[logicExIndex - 1]) + logicExData[logicExIndex - 1].Length, 2);
}
Boolean re = (Boolean)dt.Compute(logicExData[logicExIndex], "");
result = LogicEx(result, re, logicStr);
}
return result;
}
第三步,需要创建一个总的判断,这里字符串可以是有括号,或者没有
/// <summary>
/// 表达式进行拆分,包括括号内的逻辑表达式以及没有括号的直接判断方法
/// </summary>
/// <param name="str">需要判断的表达式字符串</param>
/// <returns></returns>
public Boolean ExpressionSplit(string str)
{
Boolean result = false;
//首先判断括号,有多少个
string[] parentheses = str.Split('(');
//创建表达式判断函数
DataTable dt = new DataTable();
//有括号的情况
if (parentheses.Length > 1)
{
//先判断括号里面的
for(int parenthesesIndex = 1; parenthesesIndex < parentheses.Length; parenthesesIndex++)
{
//括号里面的内容
string ParenthData = parentheses[parenthesesIndex].Split(')')[0];
//进行替换
string reParenth = "(" + ParenthData + ")";
str = str.Replace(reParenth, LogicExpression(ParenthData).ToString());
}
//判断完括号里面后,在进行外部的判断
string[] logicExData = Regex.Split(str, @"\|\||&&", RegexOptions.IgnoreCase);
if (logicExData.Length > 1)
{
string logicStr = "||";
for (int logicExIndex = 0; logicExIndex < logicExData.Length; logicExIndex++)
{
if (logicExIndex != 0)
{
logicStr = str.Substring(str.IndexOf(logicExData[logicExIndex - 1]) + logicExData[logicExIndex - 1].Length, 2);
}
Boolean re = (Boolean)dt.Compute(logicExData[logicExIndex], "");
result = LogicEx(result, re, logicStr);
}
}
}
else
{
//没括号的情况,直接判断
string[] logicExData = Regex.Split(str, @"\|\||&&", RegexOptions.IgnoreCase);
if (logicExData.Length > 1)
{
string logicStr = "||";
for (int logicExIndex = 0; logicExIndex < logicExData.Length; logicExIndex++)
{
if (logicExIndex != 0)
{
logicStr = str.Substring(str.IndexOf(logicExData[logicExIndex - 1]) + logicExData[logicExIndex - 1].Length, 2);
}
Boolean re = (Boolean)dt.Compute(logicExData[logicExIndex], "");
result = LogicEx(result, re, logicStr);
}
}
else
{
result = (Boolean)dt.Compute(logicExData[0], "");
}
}
return result;
}
调用实现
string str = "2>3||1>2||(8>3&&7>5)";
Boolean result = class1.ExpressionSplit(str);
输出result得到为:true
总计
差不多是一个把复杂的逻辑表达式拆分成一个个简单的表达式,最后通过匹配逻辑字符串来得到最终的结果。当然如果有更好的方法可以大家一起讨论下。
其实这里的逻辑表达式我们是通过一系列操作得出来的,比如我们存在数据库是RR>=9&&RR<=11:1
通过:号,前面是逻辑表达式,如果为true,则采纳后面那个数值,至于如果把字段RR转为一个简单的逻辑表达式,先是得到RR这个字段的具体值,然后把数据库的字符串RR替换成一个具体的值,最后其实就是在判断一个简单的数字逻辑表达式。
如果想要了解更多,可以添加我VX,一起讨论:y958231955