2012-01-16 71 views
1

我试图通过在用户在文本框中输入的字符串中搜索可以识别AND,OR,NOT运算符的增强型文本框来改进过滤gridview的文本框。正则表达式asp.net

我想做一个正则表达式来分组结果,但我不是很擅长这一点,我没有得到我想要的。

的我想要的一个例子如下:

string = "build1 and build2 and build3 or build4 or not build5 and not build6" 

导致分流模式:

  • build1中和
  • build2中和
  • build3中或
  • build4中或不是
  • build5而不是
  • build6

这是因为那时我会第一时间例如与

SomeTable.Name_Of_Build = 'build1' AND 

SomeTable.Name_Of_Build = 'build2' AND代替....等等

回答

0

我可能会建议,而不是使用正则表达式组的结果你做这样的事情。我认为这会比试图猜测正确的正则表达式更强大。

string filter = "build1 and buil2 and build3 or build4 or not build5" 
list<string> filterTokens = filter.Split(new char[] {' '}) 

string gridViewFilter = "";  
bool notEqual = false; 

foreach(string token in filterTokens) 
{ 
    if(token == "and") 
    { 
     gridViewFilter += "and" 
    } 
    else if(token == "or") 
    { 
    gridViewFilter += "or" 
    } 
    else if(token == "not") 
    { 
     notEqual = true; 
    } 
    else if(notEqual) 
    { 
     gridViewFilter += "SomeTable.Name_Of_Build <> '" + token + "'"; 
     notEqual = false; 
    } 
    else 
    { 
     gridViewFilter += "SomeTable.Name_Of_Build <> '" + token + "'"; 
    } 
} 

另外,如果你真的想实现你需要考虑使用Reverse Polish Notation (RPN)一个强大的和全功能排序。它可以让你处理括号和操作顺序。一个RPN实现看起来像这样。

private bool CheckForFilterMatch(string filter, List<string> values, bool exactMatch) 
{ 
    for (int i = 0; i < values.Count; i++) 
    { 
     values[i] = values[i].ToLower(); 
    } 

    if (filter.Trim() == "") 
    { 
     return true; 
    } 

    List<string> rpn = GetPostFixNotation(filter); 

    Stack<bool> output = new Stack<bool>(); 

    foreach (string token in rpn) 
    { 
     if (IsValue(token)) 
     { 
      bool isMatch; 
      if (exactMatch) 
      { 
       isMatch = values.Contains(token.ToLower()); 
      } 
      else 
      { 
       isMatch = false; 
       foreach (string value in values) 
       { 
        isMatch = (value.IndexOf(token.ToLower()) != -1); 

        if (isMatch) break; 
       } 
      } 

      output.Push(isMatch); 
     } 
     else if (IsOperator(token)) 
     { 
      bool operand1 = output.Pop(); 
      bool operand2 = output.Pop(); 

      if (token == "&") 
      { 
       output.Push(operand1 && operand2); 
      } 
      if (token == "|") 
      { 
       output.Push(operand1 || operand2); 
      } 
     } 
    } 

    return output.Pop(); 
} 


public List<string> GetPostFixNotation(string filter) 
{ 
    if (filter == "") 
    { 
     return new List<string>(); 
    } 

    List<string> postFixNotation = new List<string>(); 

    Queue<string> output = new Queue<string>(); 
    Stack<string> operators = new Stack<string>(); 

    List<string> parsedFilter = ParseFilterTokens(filter); 

    foreach (string token in parsedFilter) 
    { 
     if (IsValue(token)) 
     { 
      output.Enqueue(token); 
     } 
     else if (IsOperatorNoParenth(token)) 
     { 
      while (operators.Count > 0 && IsOperatorNoParenth(operators.Peek())) 
      { 
       if ((operators.Count > 0 && (Precedence(token) <= Precedence(operators.Peek())))) 
       { 
        string operatorToReturn = operators.Pop(); 
        output.Enqueue(operatorToReturn); 
       } 
       else break; 
      } 

      operators.Push(token); 
     } 
     else if (token == "(") 
     { 
      operators.Push(token); 
     } 
     else if (token == ")") 
     { 
      while (operators.Count > 0 && operators.Peek() != "(") 
      { 
       output.Enqueue(operators.Pop()); 
      } 
      operators.Pop(); 
     } 
    } 

    while (operators.Count > 0) 
    { 
     output.Enqueue(operators.Pop()); 
    } 

    while (output.Count > 0) 
    { 
     postFixNotation.Add(output.Dequeue()); 
    } 

    return postFixNotation; 

} 
+0

这也是一个很好的解决方案,但我认为在你放入这里的第一个例子中,我也可以尊重括号和操作顺序。我也非常感谢你的观点! – maufonfa 2012-01-16 16:09:07

+0

谢谢,很高兴帮助。祝你好运! – 2012-01-16 16:12:19

0

试试这个正则表达式了:

(build [^ b] +)

+0

thanx的答案,但我想我没有让自己清楚。构建的话只是例子,对我来说重要的是AND,OR,而不是在字符串 – maufonfa 2012-01-16 15:45:23

2

这对我的作品

\ w +(\砂\鼻涕| \ SOR \鼻涕| \沙| \ SOR | $)

+0

这个人是伟大的人,非常感谢!它也尊重我是否将“()”添加到字符串中。但事情是我想学习如此,$是什么意思? (\ w + \ sand \ snot | \ w + \ sor \ snot | \ w + \ sand | \ w + \ sor | $) – maufonfa 2012-01-16 15:55:21

+0

$匹配字符串的结尾。 ()包含由|分隔的匹配选项。你所做的改变应该是有效的,但是有点浪费,因为你在每个或者语句中包括了\ w +(匹配任何字符),并且你还没有将它包含在$之前,所以最后的匹配被错过了。 – 2012-01-19 15:18:27