Java regex extrai valores específicos em log longo

Oct 27 2020

Tenho um texto muito longo e estou extraindo alguns valores específicos que são seguidos por algumas palavras em particular. Aqui está um exemplo do meu texto longo:

.........
FPS(FramesPerSecond)[ValMin: 29.0000, ValMax: 35.000]
.........
TotalFrames[ValMin: 100000, ValMax:200000]
.........
MemoryUsage(In MB)[ValMin:190000MB, ValMax:360000MB]
.........

aqui está o meu código:

File file = filePath.toFile();
        JSONObject jsonObject = new JSONObject();
String FPSMin="";
String FPSMax="";
String TotalFramesMin="";
String TotalFramesMax="";
String MemUsageMin="";
String MemUsageMax="";

String log = "my//log//file";

        final Matcher matcher = Pattern.compile("FPS/\(FramesPerSecond/\)/\[ValMin:");
        if(matcher.find()){
            FPSMin= matcher.end().trim();
        }

Mas não consigo fazer funcionar. Onde estou errado? Basicamente, preciso selecionar, para cada String, os valores correspondentes (máx. E mín.) Provenientes desse texto longo e armazená-los nas variáveis. Gostar

FPSMin = 29.0000
FPSMax = 35.0000
FramesMin = 100000
Etc 

Obrigado

EDIT: Eu tentei o seguinte código (em um caso de teste) para ver se a solução poderia funcionar, mas estou tendo problemas porque não consigo imprimir nada, exceto um objeto. Aqui está o código:

 @Test
    public void whenReadLargeFileJava7_thenCorrect()
            throws IOException, URISyntaxException {
        Scanner txtScan = new Scanner("path//to//file//test.txt");


        String[] FPSMin= new String[0];
        String FPSMax= "";
  
//Read File Line By Line
        while (txtScan.hasNextLine())   {
            // Print the content on the console
            String str = txtScan.nextLine();
            Pattern FPSMin= Pattern.compile("^FPS\\(FramesPerSecond\\)\\[ValMin:");
            Matcher matcher = FPSMin.matcher(str);

            if(matcher.find()){
                String MinMaxFPS= str.substring(matcher.end(), str.length()-1);
                String[] splitted = MinMaxFPS.split(",");
                FPSMin= splitted[0].split(": ");
                FPSMax = splitted[1];

            }

            System.out.println(FPSMin);
            System.out.println(FPSMax);

        }

Respostas

A.Ktns Oct 27 2020 at 15:51

Talvez seu padrão deva ser assim ^FPS\\(FramesPerSecond\\)\\[ValMin:. Eu tentei e funciona para mim.

    String line = "FPS(FramesPerSecond)[ValMin: 29.0000, ValMax: 35.000]";
    
    Pattern pattern = Pattern.compile("^FPS\\(FramesPerSecond\\)\\[ValMin:");
    
    Matcher matcher = pattern.matcher(line);
    
    if (matcher.find()) {
        
        System.out.println(line.substring(matcher.end(), line.length()-1));
        
    }
}

Dessa forma, você obtém o deslocamento da linha da qual deseja extrair os dados e, usando a função substring, você pode obter todos os caracteres começando do deslocamento até o tamanho da linha 1 (porque você não deseja obter também o caractere])

PeterWalser Oct 27 2020 at 16:27

A seguinte expressão regular corresponderá e capturará o nome, mínimo e máximo:

Pattern.compile("(.*)\\[.+:\\s*(\\d+(?:\\.\\d+)?)[A-Z]*,.+:\\s*(\\d+(?:\\.\\d+)?)[A-Z]*\\]");

Uso (extração dos grupos capturados):

String input = (".........\n" +
        "FPS(FramesPerSecond)[ValMin: 29.0000, ValMax: 35.000]\n" +
        ".........\n" +
        "TotalFrames[ValMin: 100000, ValMax:200000]\n" +
        ".........\n" +
        "MemoryUsage(In MB)[ValMin:190000MB, ValMax:360000MB]\n" +
        ".........");

for (String s : input.split("\n")) {
    Matcher matcher = pattern.matcher(s);
    if (matcher.matches()) {
        System.out.println(matcher.group(1) + ", " + matcher.group(2) + ", " + matcher.group(3));
    }
}

Resultado:

FPS (FramesPerSecond), 29,0000, 35.000
TotalFrames, 100000, 200000
MemoryUsage (em MB), 190000, 360000