1

This is the string that I have:

KLAS 282356Z 32010KT 10SM FEW090 10/M13 A2997 RMK AO2 SLP145 T01001128 10100 20072 51007

This is a weather report. I need to extract the following numbers from the report: 10/M13. It is temperature and dewpoint, where M means minus. So, the place in the String may differ and the temperature may be presented as M10/M13 or 10/13 or M10/13.

I have done the following code:

public String getTemperature (String metarIn){

    Pattern regex = Pattern.compile(".*(\\d+)\\D+(\\d+)");
    Matcher matcher = regex.matcher(metarIn);

    if (matcher.matches() && matcher.groupCount() == 1) {
        temperature = matcher.group(1);
        System.out.println(temperature);
    }

    return temperature;
}

Obviously, the regex is wrong, since the method always returns null. I have tried tens of variations but to no avail. Thanks a lot if someone can help!

3
  • the "matches()" method requires the entire input string to match. you might want to try find() instead`. Commented Jan 29, 2013 at 1:17
  • "...may be presented as M10/M13 or 10/13 or M10/13." You're missing the case 10/M13 - the one in the example string. Is that also valid, or is the example string wrong? Commented Jan 29, 2013 at 1:21
  • Yes, valid. So, a total of 4 options. Commented Jan 29, 2013 at 1:54

4 Answers 4

1

This will extract the String you seek, and it's only one line of code:

String tempAndDP = input.replaceAll(".*(?<![M\\d])(M?\\d+/M?\\d+).*", "$1");

Here's some test code:

public static void main(String[] args) throws Exception {
    String input = "KLAS 282356Z 32010KT 10SM FEW090 M01/M13 A2997 RMK AO2 SLP145 T01001128 10100 20072 51007";
    String tempAndDP = input.replaceAll(".*(?<![M\\d])(M?\\d+/M?\\d+).*", "$1");
    System.out.println(tempAndDP);
}

Output:

M01/M13
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! Close! Very close! It returns 1/M01 instead of M01/M01. There is one final step left...
0

The regex should look like:

M?\d+/M?\d+

For Java this will look like:

"M?\\d+/M?\\d+"

You might want to add a check for white space on the front and end:

"\\sM?\\d+/M?\\d+\\s"

But this will depend on where you think you are going to find the pattern, as it will not be matched if it is at the end of the string, so instead we should use:

"(^|\\s)M?\\d+/M?\\d+($|\\s)"

This specifies that if there isn't any whitespace at the end or front we must match the end of the string or the start of the string instead.

Example code used to test:

Pattern p = Pattern.compile("(^|\\s)M?\\d+/M?\\d+($|\\s)");

String test = "gibberish  M130/13 here";
Matcher m = p.matcher(test);
if (m.find())
    System.out.println(m.group().trim());

This returns: M130/13

1 Comment

It is brilliant! Working. Thank you so much!
0

Try:

    Pattern regex = Pattern.compile(".*\\sM?(\\d+)/M?(\\d+)\\s.*");
    Matcher matcher = regex.matcher(metarIn);

    if (matcher.matches() && matcher.groupCount() == 2) {
        temperature = matcher.group(1);
        System.out.println(temperature);
    }

Comments

0

Alternative for regex.

Some times a regex is not the only solution. It seems that in you case, you must get the 6th block of text. Each block is separated by a space character. So, what you need to do is count the blocks.

Considering that each block of text does NOT HAVE fixed length

Example:

String s = "KLAS 282356Z 32010KT 10SM FEW090 10/M13 A2997 RMK AO2 SLP145 T01001128 10100 20072 51007";
int spaces = 5;
int begin = 0;
while(spaces-- > 0){
    begin = s.indexOf(' ', begin)+1;
}
int end = s.indexOf(' ', begin+1);
String result = s.substring(begin, end);
System.out.println(result);

Considering that each block of text does HAVE fixed length

String s = "KLAS 282356Z 32010KT 10SM FEW090 10/M13 A2997 RMK AO2 SLP145 T01001128 10100 20072 51007";
String result = s.substring(33, s.indexOf(' ', 33));
System.out.println(result);

Prettier alternative, as pointed by Adrian:

String result = rawString.split(" ")[5];

Note that split acctualy receives a regex pattern as parameter

4 Comments

If he doesn't want to work with regex, I'd rather tell him to use String split instead of the bunch of substring/indexOf as suggested here :P String result = rawString.split(" ")[5]; that's all
It is not a suggestion to use this solution. It is a suggestion to think out of regex. ;) But.. you solution is prettier.. My solution was really verbose.. :)
I've put this alternative as an incentive to think about other solutions. There are many questions here that asks for a regex pattern when the user only needs a substring.
No, this block does not have a fixed position. Sometimes, it is 5th, sometimes it is 8th... Thanks, anyways.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.