Java regex extract specific values in long log - java

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

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)

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

Related

How can i split on a string

I have a .txt file that I browse through a bufferReader and I need to extract the last character from this String, I leave the line below
<path
action="m"
text-mod="true"
mods="true"
kind="file">branches/RO/2021Align01/CO/DGSIG-DAO/src/main/java/eu/ca/co/vo/CsoorspeWsVo.java</path>
I have the following code that takes my entire line and sets it in a list, but I just need it Cs00rspeWsVo
while ((line = bufferdReader.readLine()) != null) {
Excel4 excel4 = new Excel4();
if (line.contains("</path>")) {
int index1 = line.indexOf(">");
int index2 = line.lastIndexOf("<");
line = line.substring(index1, index2);
excel4.setName(line);
listExcel4.add(excel4);
}
}
and I only want to extract Cs00rspeWsVo from here.
can anyone help me? thanks
You can use Regex groups to get it for example
public static void main(String []args){
String input = "<path\n" +
" action=\"m\"\n" +
" text-mod=\"true\"\n" +
" mods=\"true\"\n" +
" kind=\"file\">branches/RO/2021Align01/CO/DGSIG-DAO/src/main/java/eu/ca/co/vo/CsoorspeWsVo.java</path>\n";
Pattern pattern = Pattern.compile("kind=\"file\">.+/(.+\\..+)</path>");
Matcher matcher = pattern.matcher(input);
if (matcher.find()) {
String fileName = matcher.group(1);
System.out.println(fileName);
}
}
Output will be -> CsoorspeWsVo.java
and if you want the fill path change the regex to
Pattern pattern = Pattern.compile("kind=\"file\">(.+)</path>");
The output will be:
branches/RO/2021Align01/CO/DGSIG-DAO/src/main/java/eu/ca/co/vo/CsoorspeWsVo.java
And you can get name and extension in two groups for example
Pattern pattern = Pattern.compile("kind=\"file\">.+/(.+)\\.(.+)</path>");
And inside the if
String fileName = matcher.group(1);
String fileExtension = matcher.group(2);

Get text in the URL with dynamic date - Regex Java

I need to get the text between the URL which has a date in Java
Input 1:
/test1/raw/2019-06-11/testcustomer/usr/pqr/DATA/mn/export/
Output: testcustomer
Only /raw/ remains, date will change and testcustomer will change
Input 2:
/test3/raw/2018-09-01/newcustomer/usr/pqr/DATA/mn/export/
Output: newcustomer
String url = "/test3/raw/2018-09-01/newcustomer/usr/pqr/DATA/mn/export/";
String customer = getCustomer(url);
public String getCustomer (String _url){
String source = "default";
String regex = basePath + "/raw/\\d{4}-\\d{2}-\\d{2}/usr*";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(_url);
if (m.find()) {
source = m.group(1);
} else {
logger.error("Cant get customer with regex " + regex);
}
return source;
}
It's returning 'default' :(
Your regex /raw/\\d{4}-\\d{2}-\\d{2}/usr* is missing the part for the value you want, you need a regex that find the date, and keep what's next :
/\w*/raw/[0-9-]+/(\w+)/.* or (?<=raw\/\d{4}-\d{2}-\d{2}\/)(\w+) will be good
Pattern p = Pattern.compile("/\\w*/raw/[0-9-]+/(\\w+)/.*");
Matcher m = p.matcher(str);
if (m.find()) {
String value = m.group(1);
System.out.println(value);
}
Or if it's always the 4th part, use split()
String value = str.split("/")[4];
System.out.println(value);
And here a >> code demo
Here, we can likely use raw followed by the date as a left boundary, then we would collect our desired output in a capturing group, we would add an slash and consume the rest of our string, with an expression similar to:
.+raw\/[0-9]{4}-[0-9]{2}-[0-9]{2}\/(.+?)\/.+
Demo
Test
import java.util.regex.Matcher;
import java.util.regex.Pattern;
final String regex = ".+raw\\/[0-9]{4}-[0-9]{2}-[0-9]{2}\\/(.+?)\\/.+";
final String string = "/test1/raw/2019-06-11/testcustomer/usr/pqr/DATA/mn/export/\n"
+ "/test3/raw/2018-09-01/newcustomer/usr/pqr/DATA/mn/export/";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
RegEx
If this expression wasn't desired or you wish to modify it, please visit regex101.com.
RegEx Circuit
jex.im visualizes regular expressions:

How to recover integers?

I get a string and I have to retrieve the values
Je pense que nous devons utiliser le ".slit"
if (stringReceived.contains("ID")&& stringReceived.contains("Value")) {
here is my character string:
I/RECEIVER: [1/1/0 3
I/RECEIVER: :32:11]
I/RECEIVER: Timestam
I/RECEIVER: p=946697
I/RECEIVER: 531 ID=4
I/RECEIVER: 3 Value=
I/RECEIVER: 18
I receive the value 1 byte by 1 byte.
I would like to recover the value of Timestamp, Id and Value..
You can also use regex for that. Something like:
String example="[11/2/19 9:48:25] Timestamp=1549878505 ID=4 Value=2475";
Pattern pattern=Pattern.compile(".*Timestamp=(\\d+).*ID=(\\d+).*Value=(\\d+)");
Matcher matcher = pattern.matcher(example);
while(matcher.find()) {
System.out.println("Timestamp is:" + matcher.group(1));
System.out.println("Id is:" + matcher.group(2));
System.out.println("Value is:" + matcher.group(3));
}
If the order of tokens can be different (for example ID can come before Timestamp) you can also do it. But since it looks like log which is probably structured I doubt you will need to.
First [11/2/19 9:48:25] seems unnecessary so let's remove it by jumping right into "Timestamp".
Using indexOf(), we can find where Timestamp starts.
// "Timestamp=1549878505 ID=4 Value=2475"
line = line.substring(line.indexOf("Timestamp"));
Since each string is separated by space, we can split it.
// ["Timestamp=1549878505", "ID=4" ,"Value=2475"]
line.split(" ");
Now for each tokens, we can substring it using index of '=' and parse it into string.
for(String token: line.split(" ")) {
int v = Integer.parseInt(token.substring(token.indexOf('=') + 1));
System.out.println(v);
}
Hope that helps :)
String text = "Timestamp=1549878505 ID=4 Value=2475";
Pattern p = Pattern.compile("ID=(\\d)");
Matcher m = p.matcher(text);
if (m.find()) {
System.out.println(m.group(1));
}
output
4
A simple regex is also an option:
private int fromString(String data, String key) {
Pattern pattern = Pattern.compile(key + "=(\\d*)");
Matcher matcher = pattern.matcher(data);
if (matcher.find()) {
return Integer.parseInt(matcher.group(1));
}
return -1;
}
private void test(String data, String key) {
System.out.println(key + " = " + fromString(data, key));
}
private void test() {
String test = "[11/2/19 9:48:25] Timestamp=1549878505 ID=4 Value=2475";
test(test, "Timestamp");
test(test, "ID");
test(test, "Value");
}
prints:
Timestamp = 1549878505
ID = 4
Value = 2475
You can try that:
String txt= "[11/2/19 9:48:25] Timestamp=1549878505 ID=4 Value=2475";
String re1= ".*?\\d+.*?\\d+.*?\\d+.*?\\d+.*?\\d+.*?\\d+.*?(\\d+).*?(\\d+).*?(\\d+)";
Pattern p = Pattern.compile(re1,Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
Matcher m = p.matcher(txt);
if (m.find())
{
String int1=m.group(1);
String int2=m.group(2);
String int3=m.group(3);
System.out.print("("+int1+")"+"("+int2+")"+"("+int3+")"+"\n");
}
Use below code, You will find your timestamp at index 0, id at 1 and value at 2 in List.
Pattern pattern = Pattern.compile("=\\d+");
Matcher matcher = pattern.matcher(stringToMatch);
final List<String> matches = new ArrayList<>();
while (matcher.find()) {
String ans = matcher.group(0);
matches.add(ans.substring(1, ans.length()));
}
Explaining the regex
= matches the character = literally
\d* matches a digit (equal to [0-9])
* Quantifier — Matches between zero and unlimited times, as many times as possible

Check if id in string and get value if so

I am trying to get a regex to match, then get the value with it. For example, I want to check for 1234 as an id and if present, get the status (which is 0 in this case). Basically its id:status. Here is what I am trying:
String topicStatus = "1234:0,567:1,89:2";
String someId = "1234";
String regex = "\\b"+someId+":[0-2]\\b";
if (topicStatus.matches(regex)) {
//How to get status?
}
Not only do I not know how to get the status without splitting and looping through, I don't know why it doesn't match the regex.
Any help would be appreciated. Thanks.
Use the Pattern class
String topicStatus = "1234:0,567:1,89:2";
String someId = "1234";
String regex = "\\b"+someId+":[0-2]\\b";
Pattern MY_PATTERN = Pattern.compile(regex);
Matcher m = MY_PATTERN.matcher(topicStatus);
while (m.find()) {
String s = m.group(1);
System.out.println(s);
}
The key here is to surround the position you want [0-2] in parenthesis which means it will be saved as the first group. You then access it through group(1)
I made some assumptions that your pairs we're always comma separate and then delimited by a colon. Using that I just used split.
String[] idsToCheck = topicStatus.split(",");
for(String idPair : idsToCheck)
{
String[] idPairArray = idPair.split(":");
if(idPairArray[0].equals(someId))
{
System.out.println("id : " + idPairArray[0]);
System.out.println("status: " + idPairArray[1]);
}
}

Use RegEx to extract number from coordinates

I am a beginner of Java Programming language.
When I input (1,2) into the console (brackets included), how can I write the code to extract the first and the second number using RegEx?
If there is no such expression to extract the first/second number within the brackets, I will have to change the way of inputing coordinates to x,y without the brackets and that should be a lot easier to extract numbers to be used.
Try this code:
public static void main(String[] args) {
String searchString = "(7,32)";
Pattern compile1 = Pattern.compile("\\(\\d+,");
Pattern compile2 = Pattern.compile(",\\d+\\)");
Matcher matcher1 = compile1.matcher(searchString);
Matcher matcher2 = compile2.matcher(searchString);
while (matcher1.find() && matcher2.find()) {
String group1 = matcher1.group();
String group2 = matcher2.group();
System.out.println("value 1: " + group1.substring(1, group1.length() - 1 ) + " value 2: " + group2.substring(1, group2.length() - 1 ));
}
}
Not that I think regex is the best to use here. If you know the input will be in the form of: (number, number), I would first get rid of brackets:
stringWithoutBrackets = searchString.substring(1, searchString.length()-1)
and than tokenize it with split
String[] coordiantes = stringWithoutBrackets.split(",");
Looked through Regex API and you can also do something like this:
public static void main(String[] args) {
String searchString = "(7,32)";
Pattern compile1 = Pattern.compile("(?<=\\()\\d+(?=,)");
Pattern compile2 = Pattern.compile("(?<=,)\\d+(?=\\))");
Matcher matcher1 = compile1.matcher(searchString);
Matcher matcher2 = compile2.matcher(searchString);
while (matcher1.find() && matcher2.find()) {
String group1 = matcher1.group();
String group2 = matcher2.group();
System.out.println("value 1: " + group1 + " value 2: " + group2);
}
}
The main change is that I used (?<==\)), (?=,), (?<=,), (?=\)), to search for brackets and commas but not caputre them. But I really think its an overkill for this task.

Categories

Resources