gjwo
gjwo

Reputation: 195

java regular expression comma separated numbers

I am trying to get 1 long (timestamp) and 3 floats out of the payload of a message, the string I am passing looks like this (ignore quotes):

"5737540811294,359.306580,7.948747,6.6707006621"

with this method

private static void processAnglesMsg(String s) {
   final Pattern dataTFFFsplit = Pattern.compile( "[+-]([0-9]+),"
                                                + "[+-]([0-9]*[.])?[0-9]+,"
                                                + "[+-]([0-9]*[.])?[0-9]+,"
                                                + "[+-]([0-9]*[.])?[0-9]+,");
    Matcher data = dataTFFFsplit.matcher(s.trim());
    if(data.matches()) {
        Long time = Long.parseLong(data.group(1));
        float yaw = Float.parseFloat(data.group(2));
        float pitch = Float.parseFloat(data.group(3));
        float roll = Float.parseFloat(data.group(4));
        System.out.format("Angles - [%8d] Yaw: %08.3f Pitch: %08.3f Roll: %08.3f%n",time,yaw, pitch,roll);
    } else {
        if(debugLevel>=4) System.out.println("DEBUG processAnglesMsg: "+s);
    }
}

I keep reaching the debug code with:

DEBUG processAnglesMsg: 5737540811294,359.306580,7.948747,6.6707006621*

so it looks like the pattern I have is not working and data.matches() is returning false, despite much searching I can't see what I have done wrong. I do want the pattern to allow for optional + or - even though my current data doesn't contain this.

Upvotes: 0

Views: 1137

Answers (2)

Bohemian
Bohemian

Reputation: 424983

Use a scanner:

Scanner scanner = new Scanner(input).useDelimiter(",");
long time = scanner.nextLong();
float yaw = scanner.nextFloat();
float pitch = scanner.nextFloat();
float roll = scanner.nextFloat();

Easier to code and easier to read.


If the input will not always match:

Scanner scanner = new Scanner(input).useDelimiter(",");
try {
    long time = scanner.nextLong();
    float yaw = scanner.nextFloat();
    float pitch = scanner.nextFloat();
    float roll = scanner.nextFloat();
    System.out.format("Angles - [%8d] Yaw: %08.3f Pitch: %08.3f Roll: %08.3f%n",time,yaw, pitch,roll);
} catch (NoSuchElementException e) {
    // input didn't match due to insufficient elements or parsing failure
}

Upvotes: 1

Mena
Mena

Reputation: 48404

The problem with your sub-Patterns is that the + / - sign is not optional and will not match in your example (also the last sub-pattern requires a comma, but your example doesn't end with one).

Assuming your example Strings will never contain a comma for localized number separating purposes, and that you do not want to use a CSV parsing framework:

String example = "5737540811294,359.306580,7.948747,6.6707006621";
// splits the input based on comma
String[] split = example.split(",");
// parses desired data types
// will throw runtime NumberFormatException if something's un-parseable
System.out.println(Long.parseLong(split[0]));
System.out.println(Float.parseFloat(split[1]));
System.out.println(Float.parseFloat(split[2]));
System.out.println(Float.parseFloat(split[3]));

Output (values rounded)

5737540811294
359.30658
7.948747
6.6707006

Note

You can also use BigDecimal instead of Float if you wish to keep as many decimals as possible.

For instance:

System.out.println(new BigDecimal(split[3]));

Output

6.6707006621

Upvotes: 3

Related Questions