简体   繁体   中英

Extracting a value from a String using subString

In the below someString String I want to remove FAIL: and extract the last ID_ number and ignore all other ID_ number in the string. Why does the method in the first system.out doesn't work but the second one does?

Or what is the best way to achieve this?

public static void main(String[] args) {
    String someString = "FAIL: some random message with ID_temptemptemp and with original ID_1234567890";
    System.out.println(someString.split("FAIL: ")[1].substring(someString.lastIndexOf("ID_")));
    String newString = someString.split("FAIL: ")[1];
    System.out.println(newString.substring(newString.lastIndexOf("ID_") + 3));
}

Output:
4567890
1234567890

Another way would be to split on space and then use replace

 String test = "FAIL: some random message with 
                  ID_temptemptemp and with original ID_1234567890";

String arr[] = test.split (" ");
System.out.println(arr[arr.length -1].replace("ID_", ""));
Arrays.stream(str.split(" "))
    .filter(x -> x.startsWith("ID_"))
    .map(x -> x.substring(3))
    .reduce((x, y) -> y)
    .ifPresent(System.out::println);

or

String id = Arrays.stream(str.split(" "))
    .filter(x -> x.startsWith("ID_"))
    .map(x -> x.substring(3))
    .reduce((x, y) -> y)
    .orElse(null);

In my opinion, this sort of problem is usually best to use regular expression. While using a combination of replace substring indexOf can work but it can be difficult for the next dev to understand the real logic.

This is the regular expression solution:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class testmain {

    public static void main(String[] args) {
        String someString = "FAIL: some random message with ID_temptemptemp and with original ID_1234567890";
        Pattern pattern3 = Pattern.compile("ID_(\\d+)");
        Matcher matcher3 = pattern3.matcher(someString);
        String s = null; 
        while (matcher3.find()) {
            s = matcher3.group(1); // Keep overriding until the last set of captured value
        }
        System.out.println(s);
    }
}

Sample output:

1234567890

The expression ID_(\\\\d+) means that we are looking for occurrances of the word "ID_" and if matched, capture the remaining digits.

The following while loop is just to go through all the captured patterns and keep overriding the s variable with the captures until the last one, which fits your requirement.

The original problem:

The issue with your initial solution was that after you did a .split(...) the length of the splited value in position [1] string is no longer the same as the original string value, and hence you should be doing lastIndexOf(someString.split("FAIL: ")[1]) instead to compare.

Therefore giving you the output ID_1234567890

Example:

System.out.println(someString.split("FAIL: ")[1].substring(someString.split("FAIL: ")[1].lastIndexOf("ID_")));

The remaining code works just fine.

Tips:

Tips on debugging, maybe get an IDE like IntelliJ and step through the code to see what the code is doing on each step. This would give you a better idea.

You first attempt does not work because once you have done this someString.split("FAIL: ")[1] the immutable string "someString" was split and two new string objects were created. So substring(someString.lastIndexOf("ID_")) goes wrong becuase you are trying to use the length from original string for a substring operation for a smaller string

The best way to solve this as I see it is someString.substring(someString.lastIndexOf("ID_") + 3) Because I see no use of stripping out "FAIL" part

It works in the second one because you String is immutable and cannot be replaced inline.

In the first one you try to do it inline and hence it fails. But in the second one you do replace and store it in another string:

String newString = someString.split("FAIL: ")[1];
System.out.println(newString.substring(newString.lastIndexOf("ID_") + 3));

If you want to use inline then you may try StringBuffer and StringBuilder

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM