将规则条件转换为规则列表

时间:2014-04-15 13:35:43

标签: c#

我有一个字符串,它是我必须提取到数组中的规则组合。 AND条件用逗号分隔,OR移到下一个数组索引下面是我正在尝试的一些条件

(1 AND 2) AND (3 AND 4) => ["1,2,3,4"]
1 OR 2                  => ["1","2"]
(1 OR (2 AND 3)) AND 4  => ["1,4","2,3,4"]
(1 OR 2) OR (3 OR 4)    => ["1","2","3","4"]

我尝试过以下方法是否有比这更好的方法。

static void Main(string[] args)
{

    string input = "4 AND (1 OR (2 AND 3))";
    List<string> output = new List<string>();

    string inputTmp = input.Replace("(", "")
            .Replace(")", "")
            .Replace(" AND ", ",");

    if (inputTmp.Contains("OR"))
    {
        List<string> orOutput = new List<string>();
        List<List<string>> cmbOutput = new List<List<string>>();
        char splitChar = ' ';
        if (input.Contains(")) AND ((")) { inputTmp = input.Replace(")) AND ((", "&"); splitChar = '&'; }
        else { if (input.Contains(")) AND ")) { inputTmp = input.Replace(")) AND ", "&"); splitChar = '&'; } }

        if (input.Contains(")) OR ((")) { inputTmp = input.Replace(")) OR ((", "|"); splitChar = '|'; }
        else { if (input.Contains(")) OR ")) { inputTmp = input.Replace(")) OR ", "|"); splitChar = '|'; } }

        if (splitChar != ' ')
        {
            foreach (var item in inputTmp.Split(splitChar))
            {
                orOutput.Add(item.Replace("(", "").Replace(")", "").Replace(" AND ", ","));
            }
        }
        else
        {
            orOutput.Add(input.Replace("(", "").Replace(")", "").Replace(" AND ", ","));
        }


        foreach (var item in orOutput)
        {
            List<string> lcOutput = new List<string>();
            foreach (var oritem in item.Replace(" OR ", "|").Split('|'))
            {
                lcOutput.Add(oritem);
            }
            cmbOutput.Add(lcOutput);
        }

        if (cmbOutput.Count > 1 && splitChar == '&')
        {
            for (int i = 0; i < cmbOutput[0].Count; i++)
            {
                for (int j = 0; j < cmbOutput[1].Count; j++)
                {
                    output.Add(cmbOutput[0][i] + "," + cmbOutput[1][j]);
                }
            }
        }
        else
        {
            foreach (var item in cmbOutput)
            {
                foreach (var initem in item) { output.Add(initem); }
            }
        }
    }
    else
    {
        output.Add(inputTmp);
    }

    output.ForEach(o => { Console.WriteLine(o); });
    Console.ReadLine();
}

1 个答案:

答案 0 :(得分:3)

我已经创建了一种方法,希望能满足您的需求。它递归地解析给定的表达式。

源代码

public static string Parse(string s)
{
    return '"' + InnerParse(s).Replace(";", "\",\"") + '"';
}

private static string InnerParse(string s)
{
    int pos;
    while ((pos = s.IndexOf('(')) != -1)
    {
        int count = 1;
        int nextPos = pos;
        while (count != 0)
        {
            nextPos = s.IndexOfAny(new[] { ')', '(' }, nextPos + 1);
            if (nextPos == -1 || nextPos >= s.Length)
                throw new ApplicationException();   // Unpaired parentheses
            count = s[nextPos] == '(' ? count + 1 : count - 1;
        }
        s = (pos != 0 ? s.Substring(0, pos - 1) : String.Empty)
            + InnerParse(s.Substring(pos + 1, nextPos - pos - 1))   // Recursion
            + s.Substring(nextPos + 1);
    }
    string[] operands = s.Split(new[] { "AND", "OR" }, StringSplitOptions.None);
    if (operands.Length != 2)
        throw new ApplicationException();   // Count of operands != 2
    string op1 = operands[0].Trim();
    string op2 = operands[1].Trim();

    // If operator is OR
    if (s.Contains("OR"))
        return op1 + ';' + op2;

    // If operator is AND
    string[] op1s = op1.Split(';');
    string[] op2s = op2.Split(';');
    string[] ret = new string[op1s.Length * op2s.Length];
    int i = 0;
    foreach (string s1 in op1s)
        foreach (string s2 in op2s)
            ret[i++] = s1 + ',' + s2;
    return String.Join(";", ret);
}

使用示例

Console.WriteLine(Parse("(1 OR (2 AND 3)) AND 4"));

<强>限制

  1. 识别出两位运营商:ANDOR
  2. 运营商区分大小写。
  3. 运营商只有两个操作数。
  4. 操作数不能包含双引号"或分号;