Reputation: 1231
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
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
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.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