简体   繁体   中英

Java Regex: Extracting info from string to variables

I'm extracting three parts of a string with regex in Java and the following working code. I'm relatively new in regex and I'm feeling a bit silly using several expressions for such a simple search and extraction.

Can anyone of you help me with a more elegant and simple solution? I need the data to be stored in three seperate variables as the code suggests.

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

public class Test {

    public static void main(String[] args) {

        String input = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";

        String lat = regexSearch("(?<=lat: )\\d+.\\d+", input);
        String lng = regexSearch("(?<=long: )\\d+.\\d+", input);
        String imei = regexSearch("(?<=imei:)\\d+", input);

        if (lat != null && lng != null && imei != null) {
            System.out.println(lat);
            System.out.println(lng);
            System.out.println(imei);
        }
    }

    public static String regexSearch(String regex, String input) {
        Matcher m = Pattern.compile(regex).matcher(input);
        if (m.find()) return m.group();
        return null;
    }

}

Output:

56.894205
008.528896
12345678901

Edit: I need the code to handle varying length of the "lat" and "long" data (eg 56.89405 and 56.894059 etc.)

You could use Named Capturing Groups to separate the match groups and then assign each match group to a string variable of your choice. Below is a working example you can go off of ...

String s  = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";
Pattern p = Pattern.compile("lat: (?<lat>\\d+\\.\\d+) long: (?<lng>\\d+\\.\\d+).*imei:(?<imei>\\d+)");
Matcher m = p.matcher(s);
while (m.find()) {
    String lat  = m.group("lat");
    String lng  = m.group("lng");
    String imei = m.group("imei");
    System.out.println(lat);  //=> "56.894205"
    System.out.println(lng);  //=> "008.528896"
    System.out.println(imei); //=> "12345678901"
}

The term elegant is relative and varies from person to person. So, from my perspective, you can use a single regex like this :

public static void main(String[] args) {
    String input = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";
    Pattern p = Pattern.compile("(\\d+\\.\\d+)(?!\\s\\d+)|(\\d+$)"); // negative lookahead to prevent matching of speed
    Matcher m = p.matcher(input);
    while (m.find()) {
        System.out.println(m.group());
    }

}

O/P :

56.894205
008.528896
12345678901

You can simplify the code like this:

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

public class Test {

    public static void main(String[] args) {

        String input = "lat: 56.894205 long: 008.528896 speed: 000.0 24/02/13 21:21   bat:F signal:F  imei:12345678901";

        Pattern p = Pattern.compile("lat:\\s+(?<latitude>\\d+\\.\\d+)\\s+long:\\s+(?<longitude>\\d+\\.\\d+)\\s+.+?imei:(?<imei>\\d+)");
        Matcher m = p.matcher(input);

        if (m.find()) {
            String lat = m.group("latitude");
            String lng = m.group("longitude");
            String imei = m.group("imei");

            System.out.println(lat);
            System.out.println(lng);
            System.out.println(imei);
        }
    }
}
  • Here I use one regex only for extracting the numbers. Compiling a pattern can be a costly thing.
  • I'm using named capturing groups ( (?<latitude> ...). It makes regex reading easier.
  • The value the named groups capture is retrieved with Matcher#group(String name)

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