3

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

  • 50.000 → 50
  • 50.500 → 50.5
  • 50.0500 → 50.05
  • -5 → -5
  • 50 → 50
  • 5.5 → 5.5

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.

5
  • ^(-?[\.0-9]+?)(\.0+)?$ Commented Jun 15, 2016 at 7:11
  • Like so: regex 101 ? Commented Jun 15, 2016 at 7:11
  • 1
    Which language you were using? Commented Jun 15, 2016 at 7:16
  • Is there always a decimal point? Commented Jun 15, 2016 at 7:48
  • Note that all regex approaches will break down if the String represents a number in a format that uses a different decimal separator (or uses the dot character as a grouping separator). Commented Jun 15, 2016 at 9:24

2 Answers 2

4

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

2 Comments

@WingPoon: What do you expect to get if the input is -5? There is no decimal part in it. As far as I remember, you need to remove trailing zeros in the decimal part, or did you change your mind and now want to match all up to the trailing zeros?
You must add the requirement to the question. Use ^(-?\d+)(?:\.0+|(\.\d*?)0+|\.+)?$. What is the method/code you are using?
1

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

Comments

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.