5

I want to replace all the occurrences of a group in a string.

String test = "###,##.##0.0########";
System.out.println(test);
test = test.replaceAll("\\.0(#)", "0");
System.out.println(test);

The result I am trying to obtain is ###,##.##0.000000000 Basically, I want to replace all # symbols that are trailing the .0. I've found this about dynamic replacement but I can't really make it work.

The optimal solution will not take into account the number of hashes to be replaced (if that clears any confusion).

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Alkis Kalogeris
  • 17,044
  • 15
  • 59
  • 113

3 Answers3

7
#(?!.*\\.0)

You can try this.Replace by 0.See demo.

https://regex101.com/r/yW3oJ9/12

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
vks
  • 67,027
  • 10
  • 91
  • 124
  • If I understand correctly, it goes like this : Replace every `#` but discard everything the precedes `.0` . Could you explain the `?!` ? – Alkis Kalogeris May 26 '15 at 10:11
  • @alkis `?!` is negative lookahead.It will replace every `#` which does not have `.0` ahead of it. – vks May 27 '15 at 04:50
5

You can use a simple regex to achieve your task.

#(?=#*+$)

(?=#*+$) = A positive look-ahead that checks for any # that is preceded by 0 or more # symbols before the end of string $. Edit: I am now using a possessive quantifier *+ to avoid any performance issues.

See demo

IDEONE:

String test = "###,##.##0.0###########################################";
test = test.replaceAll("#(?=#*+$)", "0");
System.out.println(test);
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Glad to help. I also think that you can even further optimize this by using possessive quantifier: `#(?=#*+$)`. I edited the answer. – Wiktor Stribiżew May 26 '15 at 10:13
  • Performance is not an issue here since we are talking about small strings, but still, it's great to know the difference. Is it possible to explain step by step the regex operation? Although the answers solve my problem, it would be great if the material existed (teach someone to fish...) – Alkis Kalogeris May 26 '15 at 10:17
  • 1
    I had an answer with a look-behind the earliest, but you said you consider an unlimited number of `#`. So, I had to think of a different approach. I also provided some links for you to "learn to fish" :) – Wiktor Stribiżew May 26 '15 at 10:19
  • Yeap, you are right, I did ask for that. So basically this `?=#` (the positive look-ahead) causes to stop when it encounters anything other than a `#` right? Thank you for the material too. – Alkis Kalogeris May 26 '15 at 10:23
  • 1
    `(?=#)` is checking if there is a `#` symbol right after. `(?=#*$)` will check if there are 0 or more `#` symbols before the end of string but will store backtracking information after each match. `#*+` will not store that backtracking information which can greatly enhance performance and avoid [catastrophic backtracking](http://www.regular-expressions.info/catastrophic.html). – Wiktor Stribiżew May 26 '15 at 10:29
2

You can split your text on "0.0" and replace just for the second part:

String[] splited = "###,##.##0.0########".split("0.0");
String finalString = splited[0] + "0.0" + splited[1].replaceAll("#","0");
hexin
  • 947
  • 7
  • 17