2016-05-10 5 views
1

ブラケットを正しく分割する式ハンドラを作成しようとしていますが、今日まではうまくいきましたが、今考えていなかった問題が発生しました。ブラケットを含む式を正しく分割する方法

最初に角括弧の内容で式を分割しようとしますが、これらが評価されたら、元のコンテンツを結果に置き換え、角括弧が残らなくなるまで処理します。

この式には、マルコス/変数が含まれている場合があります。マクロは、$ macro $で囲まれたテキストで示されます。

典型的な発現:

  1. ブラケットにより分割式、これはもたらす:式が評価される前

    ($exampleA$ * 3) + ($exampleB$/2) 
    

    マクロは、以下のような処理であるため、上記正常に動作し、置換されています2つの式:

    $exampleA$ * 3 
    $exampleB$/2 
    
  2. 各式

    9 + 3 
    
  3. 任意の括弧なしの最終的な表現は、その後に評価される:

    発現は、結果を使用して再構築され

    $exampleA$ * 3 = 3 * 3 = 9 
    $exampleB$/2 = 6/2 = 3 
    
  4. :exampleA = 3とexampleB = 6の場合、その後、評価されます

    12 
    

これは、ネストされたブラケットで表現されるまで正常に動作します使用されている:

((($exampleA$ * 3) + ($exampleB$/2) * 2) - 1) 

これは私が使用している正規表現ので、完全に壊す:中

regex("(?<=\\()[^)]*(?=\\))"); 

結果:

($exampleA$ * 3 
    $exampleB$/2 

は、どのように私は正しく私が欲しい、これをデコードすることができます上に分けられる:

$exampleA$ * 3 
    $exampleB$/2 

答えて

1

私はあなたが何をしようとしているのか正確にはわかりません。あなたが最も内側の式を一致させたい場合は、なりません。このヘルプ?:

regex("(?<=\\()[^()]*(?=\\))"); 

ところで、わざとアンバランスあなたの例では、括弧ですか?

+0

ありがとう、それは誤植でした。 – SPlatten

+0

私の答えは助けてくれますか?私がしたのは、部分式の中で括弧を開くことができないことだけでした。 –

1

従来の正規表現では、ネストされた角括弧のような再帰的構造は扱えません。

使用している正規表現の味に応じて、regex recursionを使用できる場合があります。それ以外の場合は、グループを解析するための新しい方法が必要になるでしょう。私は伝統的な方法は、スタックとして表現を表現することだと思います:空のスタックから始め、 '('、 'を見つけるときにポップ')を見つけるときに押します。

+0

問題はXML属性で使用されることです。私は属性を読み込み、結果を保持します。私は1つの簡単な解決策を推測する、私はサブ式を渡すことができますし、一致する閉じ括弧が見つからない場合、自動的に一致する1つまたは複数を追加しますか? – SPlatten

0

次の正規表現を使用する場合は、group(1)として取り込むことができます。 group(0)には括弧が含まれます。

"\\(((?:\"\\(|\\)\"|[^()])+)\\)"

それが役に立てば幸い!

1

正規表現ではこれを実際に行うことはできません。あなたは本当にこのように、再帰的な方法が必要になります。私はあなたがここにC#を使用して仮定している...しかし、あなたのアイデアを取得し、何にそれを翻訳することができるはず

using System; 
using System.Data; 
using System.Xml; 

public class Program 
{ 
    public static void Main() {   

     Console.WriteLine(EvaluateExpression("(1 + 2) * 7"));   

    } 


    public static int EvaluateExpression(string expression) { 

     // Recursively evaluate parentheses as sub expressions 
     var expr = expression.ToLower(); 
     while (expr.Contains("(")) { 

      // Find first opening bracket 
      var count = 1; 
      var pStart = expr.IndexOf("(", StringComparison.InvariantCultureIgnoreCase); 
      var pos = pStart + 1; 

      // Find matching closing bracket 
      while (pos < expr.Length && count > 0) { 
       if (expr.Substring(pos, 1) == "(") count++; 
       if (expr.Substring(pos, 1) == ")") count--; 
       pos++; 
      } 

      // Error if no matching closing bracket 
      if (count > 0) throw new InvalidOperationException("Closing parentheses not found."); 

      // Divide expression into sub expression 
      var pre = expr.Substring(0, pStart); 
      var subexpr = expr.Substring(pStart + 1, pos - pStart - 2); 
      var post = expr.Substring(pos, expr.Length - pos); 

      // Recursively evaluate the sub expression 
      expr = string.Format("{0} {1} {2}", pre, EvaluateExpression(subexpr), post); 

     } 

     // Replace this line with you're own logic to evaluate 'expr', a sub expression with any brackets removed. 
     return (int)new DataTable().Compute(expr, null); 

    } 

} 

関連する問題