Wing Poon
Wing Poon

Reputation: 1231

Regex to truncate trailing zeroes

I'm trying to construct a single regex (for Java) to truncate trailing zeros past the decimal point. e.g.

Idea is to represent the real number (or integer) in the most compact form possible.

Here's what I've constructed:

^(-?[.0-9]+?)\.?0+$

I'm using $1 to capture the truncated number string.

The problem with the pattern above is that 50 gets truncated to 5. I need some way to express that the 0+ must follow a . (decimal point).
I've tried using negative-behind, but couldn't get any matches.

Upvotes: 3

Views: 2197

Answers (2)

engineer14
engineer14

Reputation: 617

For a general regex which should do the trick:

^\d+?0*\.??\d*?(?=0*?[^\d]*$)

You can replace the caret and dollar sign with whatever your boundaries should be. Those could be replaced by whatever you would expect around your number.

basically:

/d+? non-greedy match for any number (needs at least 1 number to start the match)

\.*?? optional match for a decimal. Prefers to match 0 occurrences

\d*? (?=0*?[^\d]*$) - non-greedy match for a number, but would stop at the 0 which is proceeded by a non-number

EDIT: I just realized the original expression also trimmed the last zero on integers, this should work. I added the option 0 match to catch that

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626738

The best solution could be using built-in language-specific methods for that task.

If you cannot use them, you may use

^(-?\d+)(?:\.0+|(\.\d*?)0+|\.+)?$

And replace with $1$2.

See the regex demo. Adjust the regex accordingly. Here is the explanation:

  • ^ - start of string
  • (-?\d+) -Group 1 capturing 1 or 0 minus symbols and then 1 or more digits
  • (?:\.0+|(\.\d*?)0+|\.+)? - An optional (matches 1 or 0 times due to the trailing ?) non-capturing group matching 3 alternatives:
    • \.0+ - a decimal point followed with 1+ zeros
    • (\.\d*?)0+ - Group 2 capturing a dot with any 0+ digits but as few as possible and matching 1+ zeros
    • \.+ - (optional branch, you may remove it if not needed) - matches the trailing dot(s)
  • $ - end of string.

Java demo:

String s = "50.000\n50\n50.100\n50.040\n50.\n50.000\n50.500\n50\n-5";
System.out.println(s.replaceAll("(?m)^(-?\\d+)(?:\\.0+|(\\.\\d*?)0+|\\.+)?$", "$1$2"));
// => [50, 50, 50.1, 50.04, 50, 50, 50.5, 50, -5]

Upvotes: 4

Related Questions