4

I know that this is a common question and I've been through a lot of forums to figure out whats the problem in my code.

I have to read a text file with several blocks in the following format:

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()
}

I have this code to read all the file and I'd like to extract each block between the keyword "@Layout" and the keyword "return". I need also to catch all newline so later I'll be able to split each matched block into a list

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 returns size=1

3
  • Are you sure that layoutBlock length is 1? I have run the same code and it works (layoutBlock contains matched lines) Commented Dec 13, 2015 at 16:20
  • Why not try to parse the script and interrogate the class normally, rather than trying to write a regular expression to read groovy scripts? Commented Dec 13, 2015 at 16:27
  • @cybersoft I think that layoutBlock has just one element which is the entire block returned from the matcher find, and that's fine. Now I not able to split that string on each newline Commented Dec 13, 2015 at 17:57

1 Answer 1

1

I think this can potentially be a so called XY problem anyway...if the groovy source is composed only by @Layout annotated blocks of code you can use a tempered greedy token to select till the next annotation (view online demo).

Change the pattern loc as this:

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

PS: the dotall flag (?s) inside the regex and the parameter Pattern.DOTALL do the same thing (enable the so called multiline mode), use only one of them indifferently.

UPDATE

I tried your code, the problem (preserving newline) is in the method you use to slurp the file (bufferedReader.readline() remove the newline at the end of the string).

Simply readd a newline when append to allText:

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

Or you can replace all the code to slurp the file with this:

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);
Sign up to request clarification or add additional context in comments.

1 Comment

You're right, readLine() was removing newline. Thank you for your help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.