2012-01-16 11 views
1

ユーザーがテキストボックスに入力した文字列の中でこのキーワードを検索してAND、OR、NOT演算子を識別できる拡張テキストボックスを実装することで、グリッドビューをフィルタリングするテキストボックスを改善しようとしています。正規表現asp.net

結果をグループ化するために正規表現を実行しようとしていますが、これではあまりうまくいかず、私が望むものを得ることができません。次のように

私が何をしたいの例です:スプリットモードで

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

結果:

  • build1と
  • BUILD2と
  • build3または
  • build4かnot
  • build5ではなく、
  • build6

答えて

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

+0

ありがとう、幸せに助けてください。運が良かった! –

0

に、この正規表現を試してみて、私は....例えば最初に取ると

SomeTable.Name_Of_Build = 'build1' AND 

SomeTable.Name_Of_Build = 'build2' ANDと交換しますので、これは次のとおりです。

(ビルド[^ b] +)

+0

答えがわかりませんが、私は自分自身を明確にしませんでした。ビルドの言葉は単なる例です。私にとって重要なのは、AND、OR、文字列の中にはありません。 – maufonfa

2

この+ W \私

のために働く(\砂\鼻水| \砂| | \ SOR | \ SORの\鼻水$)

+0

これは素晴らしい人です、ありがとうございます!また、文字列に "()"を追加すると敬意を表します。しかし、事は私がそう学ぶことです、$は何を意味するのですか? また、私はちょっとした変更を加え、次のような表現をしています:(\ w + \ sand \ snot | \ w + \ sor \ snot | \ w + \ sand | \ w + \ sor | $) – maufonfa

+0

$ |は、|で区切られたマッチの選択肢を囲みます。あなたが行った変更はうまくいくはずですが、それぞれの文に\ w +(任意の文字にマッチするもの)を含めて、最後のマッチを見逃した$の前にそれを含めなかったので少し無駄です。 –