0

入力は 1. または 2. のいずれか、または両方の組み合わせです。

  1. 一連の
    ...
    開始ループ
      何かを設定する
    エンドループ

    開始ループ
      何かを設定する
    エンドループ
    ...

これに使用する正規表現は (startLoop.+?endLoop)+? です。各ループ ブロックをマッチャー グループとして取得します。これは、毎回 setSomething にアクセスして変更するシーケンシャルなケースでは問題なく機能します。

  1. ネストされた
    ...
    開始ループ
      setSomething1.1
      開始ループ
        setSomething2.1
        開始ループ
          setSomething3
        エンドループ
        setSomething2.2
      エンドループ
      setSomething1.2
    エンドループ
    ...

(startLoop.+?startLoop)+? のようなものを書きました。しかし、それはsetSomething1.1にしかアクセスできません

入力のループ構造のタイプに関係なく、setSomething にアクセスできる正規表現を思いつくことができません。

あなたの助けに感謝。

4

2 に答える 2

4

正規表現を使用して説明しているものをキャプチャすることはできないと思います。正規表現は通常の言語のみをキャプチャできますが、ネストされたループの状況について説明したことは、文脈自由言語に非常に似ています。チョムスキー階層によると、通常の言語は文脈自由言語の厳密なサブセットを形成するため、すべての文脈自由言語を捉えることはできません。

CFG と正規表現

文脈自由文法は、正規表現より厳密に強力です。

  • 正規表現を使用して生成できる言語は、文脈自由文法によって生成できます。
  • 正規表現では生成できない文脈自由文法で生成できる言語があります。

  • 参照: http://www.cs.rochester.edu/~nelson/courses/csc_173/grammars/cfg.html

    于 2012-01-31T09:48:10.100 に答える
    0

    これを試して、うまくいきました。それはばかげた方法ですが、今のところうまくいきます。

    private static String normalize(String input) {
        //Final string is held here
        StringBuilder markerString = new StringBuilder(input);
        //Look for the occurrences of startLoop-endLoop structures across lines
        Pattern p1 = Pattern.compile("(startLoop.+?\\endLoop)+?",Pattern.DOTALL);
        Matcher m1 = p1.matcher(markerString.toString());
        while(m1.find()){
            /* startLoop-endLoop structure found
             * Make sure length of StringBuilder remains same
             */
            markerString.setLength(input.length());
            //group will now contain the matched subsequence of the full string
            StringBuilder group = new StringBuilder(m1.group());
            /* Look for occurrences of startLoop within the matched group
             * and maintain a counter for the no of occurrences 
             */
            Pattern p2 = Pattern.compile("(startLoop)+?",Pattern.DOTALL);
            Matcher m2 = p2.matcher(group.toString());
            int loopCounter = 0;
            while(m2.find()){
                loopCounter++;
            }
            /* this takes care of the sequential loops scenario as well as matched group
             * in nested loop scenario
             */
            markerString.replace(m1.start(), m1.end(), m1.group().
                             replaceAll("setSomething", "setThisthing"));
            /* For the no of times that startLoop occurred in the matched group,
             * do the following
             * 1. Find the next index of endLoop after the matched group's end in the full string
             * 2. Read the subsequence between matched group's end and endIndex
             * 3. Replace all setSomething with setThisthing in the subsequence
             * 4. Replace subsequence in markerString
             * 5. Decrement forCounter
             */
            int previousEndIndex = m1.end();
            int currentEndIndex = -1;
            while(loopCounter>1){
                currentEndIndex = markerString.indexOf("endLoop",previousEndIndex);
                String replacerString  = markerString.substring(previousEndIndex,currentEndIndex);
                replacerString =  replacerString.replaceAll("setSomething", "setThisThing");
                markerString.replace(previousEndIndex, currentEndIndex, replacerString);
                previousEndIndex = currentEndIndex+7;
                loopCounter--;
            }
        }
        input = markerString.toString();
    }
    
    于 2012-01-31T18:44:46.190 に答える