我知道这是一个常见的问题,我已经通过很多论坛来弄清楚我的代码中的问题是什么.
我必须以下列格式读取包含多个块的文本文件:
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);