-1

I have a very long text and I'm extracting some specific values that are followed by some particular words. Here's an example of my long text:

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

here's my code:

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

But I can't make it work. Where am I wrong? Basically I need to select, for each String, the corresponding values (max and min) coming from that long text and store them into the variables. Like

FPSMin = 29.0000
FPSMax = 35.0000
FramesMin = 100000
Etc 

Thank you

EDIT: I tried the following code (in a test case) to see if the solution could work, but I'm experiencing issues because I can't print anything except an object. Here's the code:

 @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);

        }
VLAZ
  • 26,331
  • 9
  • 49
  • 67
thranduil90
  • 63
  • 1
  • 10
  • Not sure what you want to achieve but your code doesn't even compile. I often wonder why people are struggling with Regex instead of trying to use the simple way (substring) first. – Smutje Oct 27 '20 at 08:48
  • I need to select the values from the text log and store them into variables using regex. For instance, the FPS min value, the FPS max value, etc – thranduil90 Oct 27 '20 at 08:49
  • @Smutje how can I do that using substring? That's a single log file, but very long – thranduil90 Oct 27 '20 at 08:51
  • I'd suggest to simplify your example by removing every unnecessary line of code (the file part for example) to narrow down why the regex won't work. Also, that helps others to help you if they can compile your code on their machines without additional overhead. – Smutje Oct 27 '20 at 08:52

2 Answers2

0

Maybe your pattern should be like this ^FPS\\(FramesPerSecond\\)\\[ValMin: . I've tried it and it works for me.

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

In that way, you get the offset of the line that you want to extract data and using the substring function you can get all characters starting from offset until the size of the line-1 (because you dont want to get also the ] character)

A.Ktns
  • 381
  • 6
  • 12
  • Can you please show me your code? It is not working for me, and it says I need to modify the matcher to pattern – thranduil90 Oct 27 '20 at 08:57
  • @thranduil90 that's because `Pattern#compile` returns a `Pattern` and not a `Matcher`, – Smutje Oct 27 '20 at 09:06
  • That's perfect, thanks! But how can I store the Min and the Max in different variables? – thranduil90 Oct 27 '20 at 09:15
  • @Smutje Thanks, I fixed the issue with Pattern and Matcher. Now I just need to sort out how to select Min and Max and assign them to different variables – thranduil90 Oct 27 '20 at 09:19
  • One way could be to use split() function. After getting the result ValMin: 29.000, ValMax: 35.000 using the above code I mentioned, you could do `String[] splitted = result.split(",")` where result is a string to store the result of the above code and on splitted[0] you would have ValMin: 29.000 and on splitted[1] you would have ValMax: 35.000. Then in the same way you could do `String[] minVal = splitted[1].split(": ")` and on minVal[1] you will get 29.000. Similarly, do the same for ValMax – A.Ktns Oct 27 '20 at 09:21
  • I meant `String[] minVal = splitted[0].split(": ")` – A.Ktns Oct 27 '20 at 09:28
  • I've added the code I wrote, but I can't make it work. Can you please look at it? – thranduil90 Oct 27 '20 at 12:52
  • @A.Ktns the result I'm getting is a java object and not a string Ljava.lang.String;@112ds4 – thranduil90 Oct 27 '20 at 14:50
  • Sorry for the late answer. If you get an object you can cast it to String with (String) or simply do `myObject.toString()`. Check here: https://stackoverflow.com/questions/31847080/how-to-convert-any-object-to-string – A.Ktns Oct 29 '20 at 09:19
0

The following regular expression will match and capture the name, min and max:

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

Usage (extracting the captured groups):

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

Output:

FPS(FramesPerSecond), 29.0000, 35.000
TotalFrames, 100000, 200000
MemoryUsage(In MB), 190000, 360000

Peter Walser
  • 15,208
  • 4
  • 51
  • 78
  • Thanks! But the dots were just an example, there is much useless text in there. How do I modify the pattern to include only the Frames, TotalFrames and MemoryUsage? – thranduil90 Oct 27 '20 at 09:32
  • Instead of matching anything before the first square bracket `(.*)`, you then would match only `(FPS\(FramesPerSecond\)|TotalFrames|MemoryUsage\(In MB\))`. Or you use the original pattern, and filter by the first group (if the name is within the set of these three names). – Peter Walser Oct 27 '20 at 09:40