Question

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 "½"?

Was it helpful?

Solution

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

OTHER TIPS

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.

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.

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", "¼");

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", "¾");

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;
    }

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top