2016-11-26 15 views
1

私は正規表現https://regex101.com/r/PPbhRn/1を持っています。ここで私は、 "と"がキャプチャされると、上にキャプチャされた空白を見ることができます。その空白を取り除く方法はありますか?グループ化が正しく捕捉された場合にのみパターンが一致するかどうかを知りたいですか?正規表現のグループ化とマッチング

String validRegex="(((?:[(]* ?[a-z][a-z]+ ?[)]*)|[(]* ?(NOT) (?:[(]* ?[a-z][a-z]+ ?[)]*) ?[)]*)((AND|OR) ((?:[(]* ?[a-z][a-z]+ ?[)]*)|[(]* ?(NOT) (?:[(]* ?[a-z][a-z]+ ?[)]*) ?[)]*))*)"; 

    String formula = "mean AND trip OR (mean OR mango) AND (mean AND orange) OR mango AND (test OR NOT help)"; 
    Pattern p1 = Pattern.compile(validRegex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE); 
    final Matcher matcher = p1.matcher(formula); 

    boolean result=MarketMeasureUtil.isValidFormula(formula); 
    System.out.println(result); 

    while (matcher.find()) { 
     System.out.println("Full match: " + matcher.group(0)); 
     for (int i = 1; i <= matcher.groupCount(); i++) { 
      System.out.println("Group " + i + ": " + matcher.group(i)); 
      System.out.println(matcher.group() + "starting at" + "index" + matcher.start()+ "and ending at index" +matcher.end()); 

     } 

私は適切にグループをキャプチャすることはできないんだけど、私はなど。「平均値との旅」「OR」「意味やマンゴー」のようなグループをキャプチャする必要があります。.. isValidFormula()は正規表現を呼び出します。 matches()。私たちの場合、マッチはうまくいきます。グループ化が期待通りに機能しない

+4

完全一致のみにこれらのスペースが含まれています。グループ2はちょうど 'と'常に... – marekful

+0

私は言葉のような制約が述語 "AND/ORに従うべきである(リンゴとパイナップルまたは(卵)AND(パイナップル))のような文字列をキャプチャする正規表現が必要です。グループを巧みに捉える必要があります。私は上記の私はグループを正しくキャプチャすることができないと一致する正規表現を試してみると、並べ替える方法はありますか? @marekful –

+1

質問を編集し、実際の問題と試したJavaコードを表示してください。正規表現は各言語/ツールごとに若干異なりますので、私はRegex101リンクだけに基づいて答えるべきではありません。 –

答えて

0

正規表現はこのタスクには適していません。あなたが望むように多くの中括弧を追加することができれば、その式を検証することさえ可能だとは思っていません。

あなたが好きなクラスを使用して、ツリーを構築するパーサーを作成する必要があります。

class Node { 

    boolean[] isAnd = null; 
    Node[] children = null; 
    String literal = null; 

    Node(String literal) { // creator for literals 
     this.literal = literal; 
    } 

    Node(boolean[] isAnd) { // creator for intermediate nodes 
     this.isAnd = isAnd; 
     children = new Node[isAnd.length + 1]; 
    } 

} 

を、メソッドが次のようになります。

Node parse(String) throws ParseException { // returns the root 

まずあなたが余計な括弧を削除することができますすべての中カッコを数えて右と左を比較すると0レベルandor(すなわち中カッコではないもの)が見つかることができ、0レベルが見つからない場合は中間ノードを作成しますand sおよびor■文字列はリテラルでなければならないか、無効です。中間ノードの場合は、parseメソッドを0レベルのサブ文字列andorに再帰的に呼び出して子を追加します。

0

DSLを作成したようです。 "言語"が複雑でない場合は、パーサの使用や独自の実装を検討する必要があります。

OR/AND演算を評価すると仮定します。これは、AND(乗算)がOR(加算)より優先する電卓のコードと非常によく似ています。したがって、自分で実装することができます。 最初に文をトークン化して検証することはできますが、同時に正規表現で両方を実行しようとしないでください。検証が唯一の目的なら、ここで終了できます。 次の式を評価する必要がある場合は、トークン(たとえば、左の葉としてORオペランド、右の葉としてANDのオペランド)を使用してバイナリツリーを作成し、文法を適用して式を評価できます。

+0

いいえ、私は式を検証する必要はありません、私はそれを評価したくないです。私は "(リンゴAND(ornage OR Kiwi))"のようにパタンを必要とします。 regex.matches()の部分はmwでうまく動作します。しかし、私はundestandグループ化することができない –