user2543930
user2543930

Reputation:

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 (e.g. 56.89405 and 56.894059 etc.)

Upvotes: 3

Views: 3458

Answers (3)

hwnd
hwnd

Reputation: 70750

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"
}

Upvotes: 4

Stephan
Stephan

Reputation: 43053

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)

Upvotes: 1

TheLostMind
TheLostMind

Reputation: 36304

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

Upvotes: 0

Related Questions