简体   繁体   中英

Dollar sign replacement not working Java

Okay so I've been reading posts(alot) about the $ sign in java and regex and stuff. But for some reason, each time I try to replace it, it gives me an IndexOutOfBoundsException .

I'm trying to parse a string begining with a $ sign into an integer.

When I do $test it gives me a NumberFormatException (which is what I want) but when I do $5 it gives me the other Exception ( IndexOutOfBoundsException ) although i'm changing it to \\0024 and adding in the number following it... Anyone mind helping me? Thanks!

if (w.charAt(0) == '$') {
    try {
        w = w.replace("\u0024", "");
        int i = Integer.parseInt(w);
        m.appendReplacement(sb, ChatTweaks.Citrus.get("dollarIn") + "" + '\u0024' + i);
    } catch (NumberFormatException nume) {
        ChatTweaks.showMsg(ChatTweaks.prefix + "Please use numbers after your dollar signs ($)w=" + w);
        return;
    } catch (Exception ex){
        ChatTweaks.showMsg(ChatTweaks.prefix + "Unknown exception ex: " + ex + " w:" + w);
    }
}

Your replacement code works fine for me, but... why use the regex to remove the first character? This is more straightforward, and works just as well:

w = w.substring(w.length()-1)

Also, for code readability, '$' and "$" are just fine - since '$' is a single-byte character, it should be equivalent to '\\u002\u0026#39; - or do you have some special requirement?

See http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html for a semi-humorous outlook on why regex probably shouldn't be the first thing that comes to mind when you're trying to solve a text-manipulation problem.

\$ is the Unicode escape sequence for the dollar sign. Your code is checking for the dollar sign ( w.charAt(0) == '$' ), removing it ( w = w.replace("\$", "") ), then putting it back again ( '\$' + i ).

Edit: I knew this was strange, but I missed the actual problem. I see now; Matcher.appendReplacement is complaining because there is a $+number sequence in the replacement, and is treating it as a reference to a captured group.

This is because \$ does not escape anything as far as appendReplacement is concerned, because that escape sequence is parsed at compile time. By run time, a string written in the source as "\$" has length 1 , and its only character is a literal dollar sign. (In fact, Unicode escape sequences are almost the first thing parsed by the Java compiler, right after counting lines. For example, you can declare a variable int $foo; and then use it in code (outside of regexes or even strings) with \$foo = 123; (or \$\f\o\o = 123; )).

To escape a dollar sign for appendReplacement, escape it with a backslash. Because escape sequences in strings are parsed at compile time, you must also escape the backslash. Ie,

m.appendReplacement(sb, ChatTweaks.Citrus.get("dollarIn") + "\\$" + i);

To clarify, at compile time, the compiler sees "\\\\$" and creates a string of length 2; whose characters are \\ and $. At run time, appendReplacement can see them and insert just a $.

The method Matcher.quoteReplacement can also do this for you, which is a good idea in case ChatTweaks.Citrus.get("dollarIn") could also return any dollar signs that it's not supposed to and which would also upset the matcher. Eg,

m.appendReplacement(sb,
    Matcher.quoteReplacement(ChatTweaks.Citrus.get("dollarIn") + "$" + i));

Replacing and parsing as you coded, is working for me. String.replace(String,String) will not consider the argument as a regex. If you want to pass a regex as argument, use String.replaceAll(String,String) or String.replaceFirst(String,String) .

String.replaceAll replaces all patterns matching the regex given as first argument with the string given as second argument.

String.replaceFirst replaces first pattern matching the regex given as first argument.

So use w.replace("$", "") if you want to replace every $ sign in w . Here, "$" is not treated as a regex.

Or use w.replaceAll("\\\\$","") . Here "\\\\$" is treated as regex.

Or use w.replaceFirst("\\\\$","") if you want to replace only the first $ in the string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM