String replaceAll("¾") in java
Asked Answered
M

7

19

I have really weird error in my java code and can not figure out what is wrong.

Let's say I have this code:

private void test()
{
    String test1 = replace("1.25");
    String test2 = replace("1.5");
    String test3 = replace("1.75");
}

private String replace(String s)
{
     s = s.replaceAll(".25", "¼");
     s = s.replaceAll(".5", "½");
     s = s.replaceAll(".75", "¾");
     return s;
}

Then the result will be:

test1 = "¼"

test2 = "½"

test3 = "½" ??????????

Can someone please explain why test3 becomes "½"?

Mandatory answered 19/12, 2013 at 15:55 Comment(2)
Do an alert(s); just before you peform the third replaceAll. See what value is coming in.Strangulate
s = s.replaceAll(Pattern.quote(".25"), "¼");Kidding
C
27

You're using replaceAll(), which takes a regular expression. In regex-land, . means "any character". Use replace() instead, which works with literal strings.

Curling answered 19/12, 2013 at 15:57 Comment(1)
Or use Pattern#quote.Kidding
D
8

Because replaceAll takes a regular expression. That means . is interpreted as a wildcard that also matches 7 so that .5 matches 75. You can escape in regular expressions using \ but note that this is also a String which means you will have to escape twice: so replaceAll("\\.5", "½") will do what you wanted.

Drear answered 19/12, 2013 at 15:57 Comment(1)
yes but in fact it's not false and not out off topic in that case, the least that can be done is no vote or upvote but downvote is definitly irrelevant and there is less than one minute between the two answer which make it makes a downvote even more innapropriate.Subadar
K
5

The problem is that in a regular expression . means any character. replaceAll takes a regex as a parameter so you should use some other means such as replace.

Klapp answered 19/12, 2013 at 15:58 Comment(3)
I did not see his answer when I was writing mine.Klapp
I think you need to take a happy-pill :)Klapp
A couple of happy pills later and on reflection, you're correct. I've withdrawn my downvote.Froebel
P
3

The replace all function interprets the first argument as a regular expression. ".5" as a regular expression will match anything followed by a 5, like your string test2. Escape the '.' character with a backslash:

 s = s.replaceAll("\\.25", "¼");
Pallmall answered 19/12, 2013 at 15:58 Comment(3)
Should be a double backslash!Girandole
Are you sure? The backslash is not a literal, it's meant to escape the . character (must admit I haven't tried this in Java, but other regex implementations allow this)Pallmall
Oh yeah you're right, because this is a string as @MartinRing explainsPallmall
H
3

replaceAll uses regex as first parameter that will need to be found and dot . in regex is metacharacter which will match all characters except new line. So when you are using

s = s.replaceAll(".5", "½");

on "1.75" .5 can match 75 (since . matches all). So after such change

1.75 
  -- will become 
1.½ 

(notice that 1.25 works correctly only because you used .25 before .5)

To prevent such behaviour you need to escape dot. You can do it by

  • placing \ before it (remember that to create \ literal you need to write it as "\\") "\\.",
  • place it in character class [.],
  • surround it with \Q and \E which represent start and end of quote \\Q.\\E
  • surrounding with \Q and \E can be also done with Pattern.quote(".")
  • In case of Pattern instance while compiling you can add Pattern.LITERAL flag to make all metacharacters used in pattern literals.

If you want our entire pattern be simple literal you can use replace instead of replaceAll which will automatically use Pattern.LITERAL flag and change all regex metacharacters into simple literals.

So you can try something like

return s.replaceAll("\\.25", "¼").replaceAll("\\.5", "½").replaceAll("\\.75", "¾");

or simpler

return s.replace(".25", "¼").replace(".5", "½").replace(".75", "¾");
Hibernate answered 19/12, 2013 at 16:13 Comment(1)
this explain very well, thank you for taking the time and wrote a really good answerMandatory
S
1

The first parameter of replaceAll() is a REGEX, and '.' means any character in REGEX area.

Satirize answered 19/12, 2013 at 15:59 Comment(0)
G
1

Use String.replace() instead of String.replaceAll()

Do like this

    private String replace(String s)
    {
        s = s.replace(".25", "¼");
        s = s.replace(".5", "½");
        s = s.replace(".75", "¾");
        return s;
    }
Gesticulation answered 19/12, 2013 at 16:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.