0

输入可以是 1. 或 2. 或两者的组合。

  1. 顺序的
    ...
    开始循环
      setSomething
    结束循环

    开始循环
      setSomething
    结束循环
    ...

我为此使用的正则表达式是 (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 回答