Java – Groovy:正则表达式解析文本块

我知道这是一个常见的问题,我已经通过很多论坛来弄清楚我的代码中的问题是什么.

我必须以下列格式读取包含多个块的文本文件:

import com.myCompanyExample.gui.Layout

/*some comments here*/

@Layout
LayoutModel currentState() {
   MyBuilder builder = new MyBuilder()
   form example
     title form{
        row_1
        row_1 
        row_n
      }
   return build.get()
}

@Layout
LayoutModel otherState() {
   ....
   ....
   return build.get()
}

我有这个代码来读取所有文件,我想提取关键字“@Layout”和关键字“return”之间的每个块.我还需要捕获所有换行符,以便稍后我将能够将每个匹配的块拆分成一个列表

private void myReadFile(File fileLayout){
    String line = null;
    StringBuilder allText = new StringBuilder();
    try{
        FileReader fileReader = new FileReader(fileLayout);
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        while((line = bufferedReader.readLine()) != null) {
            allText.append(line)
        }
        bufferedReader.close();
    }
    catch(FileNotFoundException ex) {
        System.out.println("Unable to open file");
    }
    catch(IOException ex) {
        System.out.println("Error reading file");
    }
    Pattern pattern = Pattern.compile("(?s)@Layout.*?return",Pattern.DOTALL);
    Matcher matcher = pattern.matcher(allText);
    while(matcher.find()){
       String [] layoutBlock = (matcher.group()).split("\\r?\\n")
      for(index in layoutBlock){
           //check each line of the current block
      }
}

layoutBlock返回size = 1

最佳答案 我认为这可能是一个所谓的XY问题…如果groovy源只由@Layout带注释的代码块组成,你可以使用一个淬火的贪婪令牌来选择直到下一个注释(查看 online demo).

将模式loc更改为:

Pattern pattern = Pattern.compile( "@Layout(?:(?!@Layout).)*", Pattern.DOTALL );

PS:正则表达式中的dotall标志(?s)和参数Pattern.DOTALL做同样的事情(启用所谓的多线模式),只使用其中一个无差别.

UPDATE

我尝试了你的代码,问题(保留换行符)在你用来粘贴文件的方法中(bufferedReader.readline()删除字符串末尾的换行符).

只需在附加到allText时读取换行符:

String ln = System.lineSeparator();
while((line = bufferedReader.readLine()) != null) {
    allText.append(line + ln);
}

或者你可以用以下代码替换所有代码来篡改文件:

import java.nio.file.Files;
import java.nio.file.Paths;

//can throw an IOException
String filePath = "/path/to/layout.groovy";
String allText = new String(Files.readAllBytes(Paths.get(filePath)),StandardCharsets.UTF_8);
点赞