15

Is this the proper REGEX to remove trailing decimal and zeroes from a string? I can't get it to work. What am I missing?

  1. 78.000 -> 78
  2. 78.008 -> 78.008

str.replaceAll("^.0*$", "");

Cody
  • 8,686
  • 18
  • 71
  • 126

3 Answers3

25

You need to escape the ., as it is a special character in Regex that matches any character. You also have to remove the ^, which anchors at the beginning of the number.

str.replaceAll("\\.0*$", "");

You can use a lookbehind if you want to make sure there is a number in front of the dot, like this:

str.replaceAll("(?<=^\\d+)\\.0*$", "");

The lookbehind (the (?<=...) part) is not a part of the match, so it will not be replaced, but it still has to match for the rest of the regex to match.

Håvard
  • 9,900
  • 1
  • 41
  • 46
  • 1
    I'm not the downvoter, but your lookbehind wont work - Java requires lookbehinds to have a maximum length, so you can't use `+` or `*` inside them. Also, you should probably improve the wording of that last sentence - a lookbehind _can_ be part of a match, it's simply that it matches a position not a character (and in this case that position is before the match). It is possible to do stuff like `str.replaceAll("(?<=whatever)","stuff")` to append text after a match. – Peter Boughton Sep 21 '11 at 00:48
  • @PeterBoughton, it seems to work fine [here](http://ideone.com/aBhHS). Are you sure about the lookbehind part? – Håvard Sep 21 '11 at 00:53
  • Hmm. I _was_ sure - I'm always forgetting and running into this problem, and having to switch to `{0,99}` or `{1,99}` instead. Now I'm confused. :/ – Peter Boughton Sep 21 '11 at 00:57
  • @PeterBoughton, I looked it up: http://stackoverflow.com/questions/1536915/regex-look-behind-without-obvious-maximum-length-in-java . Apparently, the match in the lookbehind has to be shorter than `Integer.MAX_VALUE`. Also, `+` is implemented as `{1,0x7FFFFFFF}`. Thus, since there is only one character in the lookbehind (`\d`), it will work. But if I add one more, like [here](http://ideone.com/JcHGw) it fails. – Håvard Sep 21 '11 at 01:05
  • Ok, well I'm not going crazy, but I don't know what's up either... Doing `\d*` works. Doing `\d+` works. Doing `\d\d*` throws the error "Look-behind group does not have an obvious maximum length near index 8" http://ideone.com/6mRfk – Peter Boughton Sep 21 '11 at 01:09
  • Ah, just seen that comment after I submitted mine... that at least explains the behaviour. Wish it could be smarter and just limit the whole lookbehind to MAX_VALUE, no matter how many characters/quantifiers it contained. – Peter Boughton Sep 21 '11 at 01:13
  • It's because the maximum possible length of the lookbehind exceeds `Integer.MAX_VALUE`. `\d*` has the maximum length of `0x7FFFFFFF`, or `Integer.MAX_VALUE`. If you add another `\d`, it becomes `Integer.MAX_VALUE + 1`, and you have an error. – Håvard Sep 21 '11 at 01:13
  • Yeah, I understand now - I was simply saying it'd be nice if it detected/avoided that error and limited the `\d*` to `0x7FFFFFFF - [length of fixed portion]`. Meh. – Peter Boughton Sep 21 '11 at 01:18
  • This is all great discussion - thank you all! Especially the example, thanks @Harpyon. – Cody Sep 21 '11 at 12:26
  • Does not handle 1.230->1.23 – user1332148 Nov 11 '16 at 22:30
5

Nope. Use this:

str.replaceAll("[.0]+$", "");
Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
4

Get rid of the ^, which matches the start of the string. You also need to escape ., since it's a regex meta character that matches any character (except newlines):

str.replaceAll("\\.0*$", "");

Demo: http://ideone.com/RSJrO

NullUserException
  • 83,810
  • 28
  • 209
  • 234