3

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.)

5
  • 2
    This question would be better suited for Code Review. Commented Jan 22, 2015 at 13:25
  • In your place, I would work with substring, indexOf("lat: ") and so on to avoid three compiled regular expressions. Commented Jan 22, 2015 at 13:27
  • Will the String will be in the same way always? Commented Jan 22, 2015 at 13:30
  • @TheLostMind: As my edit suggests, the string will be of varying length, e.g. more digits in the lat and long info. Commented Jan 22, 2015 at 13:34
  • @SimonGregersen - If the format / pattern of the String will remain the same, then you might look at my solution Commented Jan 22, 2015 at 13:35

3 Answers 3

4

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"
}
Sign up to request clarification or add additional context in comments.

Comments

1

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)

Comments

0

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

3 Comments

How do I extract the info in seperate variables then?
@SimonGregersen - You could add them to a list and then get values from list . at pos 0, you will have lattitude, at pos1 you will have longitude and at pos 2 you will have imei number
@AvinashRaj - Then this answer won't work.. He can use his regex or something else. He might actually use split then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.