美元符号替换不工作Java

时间:2013-01-28 03:05:50

标签: java regex

好的,所以我一直在阅读有关java和正则表达式中$符号的帖子(很多)。但出于某种原因,每次我尝试替换它时,它都会给我一个IndexOutOfBoundsException

我正在尝试将一个以$符号开头的字符串解析为整数。

当我$test时,它会给我一个NumberFormatException(这就是我想要的)但是当我$5时,它会给我另一个例外(IndexOutOfBoundsException)我正在将其更改为\0024并添加其后的数字......任何人都在帮助我吗?谢谢!

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

3 个答案:

答案 0 :(得分:2)

您的替换代码对我来说很好,但...... 为什么用正则表达式删除第一个字符?这更直截了当,同样有效:

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

此外,为了代码可读性,' $'和" $"很好 - 因为' $'是一个单字节字符,它应该等同于' \ u002' - 或者你有什么特殊要求吗?

请参阅http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html,了解为什么正则表达式可能不是您尝试解决文本操作问题时首先想到的原因。

答案 1 :(得分:1)

\u0024是美元符号的Unicode转义序列。您的代码正在检查美元符号(w.charAt(0) == '$'),将其删除(w = w.replace("\u0024", "")),然后再将其重新设置('\u0024' + i)。

编辑:我知道这很奇怪,但我错过了实际问题。我现在明白了; Matcher.appendReplacement抱怨,因为替换中有一个$ +数字序列,并将其视为对捕获组的引用。

这是因为\u0024对于appendReplacement而言转义任何东西,因为该转义序列在编译时被解析。根据运行时间,在源中写为"\u0024"的字符串长度 1 ,其唯一字符是文字​​美元符号。 (实际上,Unicode转义序列几乎是Java编译器在计算行之后解析的第一个东西。例如,您可以声明变量int $foo;然后在代码中使用它(在正则表达式甚至字符串之外)使用\u0024foo = 123;(或\u0024\u0066\u006f\u006f = 123;))。

要为appendReplacement转义美元符号,请使用反斜杠转义它。因为字符串中的转义序列在编译时被解析,所以您还必须转义反斜杠。即,

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

为了澄清,在编译时,编译器会看到"\\$"并创建一个长度为2的字符串;其字符是\和$。在运行时,appendReplacement可以看到它们并只插入$。

方法Matcher.quoteReplacement也可以为你做这件事,这是一个好主意,以防ChatTweaks.Citrus.get("dollarIn")也可以返回任何不应该的美元符号,哪些也会扰乱匹配器。如,

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

答案 2 :(得分:0)

在编码时替换和解析,对我有用。 String.replace(String,String)不会将该论点视为正则表达式。如果要将正则表达式作为参数传递,请使用String.replaceAll(String,String)String.replaceFirst(String,String)

String.replaceAll将作为第一个参数给出的正则表达式匹配的所有模式替换为作为第二个参数给出的字符串。

String.replaceFirst替换匹配作为第一个参数给出的正则表达式的第一个模式。

如果您要替换w.replace("$", "")中的每个$符号,请使用w。在这里,"$"不被视为正则表达式。

或使用w.replaceAll("\\$","")。此处"\\$"被视为正则表达式。

如果您只想替换字符串中的第一个w.replaceFirst("\\$",""),请使用$