【问题标题】:Dollar sign replacement not working Java美元符号替换不起作用Java
【发布时间】:2013-01-11 08:52:27
【问题描述】:

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

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

当我执行$test 时,它给了我一个NumberFormatException(这是我想要的),但是当我执行$5 时,它给了我另一个异常(IndexOutOfBoundsException),尽管我将其更改为@987654328 @ 并在其后添加数字...有人介意帮助我吗?谢谢!

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

【问题讨论】:

    标签: java regex


    【解决方案1】:

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

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

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

    请参阅http://www.codinghorror.com/blog/2008/06/regular-expressions-now-you-have-two-problems.html 以半幽默的观点了解为什么在尝试解决文本处理问题时可能不应该首先想到正则表达式。

    【讨论】:

    • 问题是,当我使用 $ 符号时,它的想法是使用正则表达式....所以我知道如何取消它 D:
    • 如果“它”是指 String.replace(String, String) 方法,它只适用于正则表达式。因此,您必须转义美元符号以使其成为文字,方法是在其前面加上反斜杠,如w.replace("\$", ""),但我仍然推荐使用 substring 方法。
    • @GreyBeardedGeek:“如果说‘它’,你的意思是 String.replace(String, String) 方法,它只适用于正则表达式”。这是不正确的。 String.replaceAll 和 String.replaceFirst 是正则表达式方法。 String.replace 进行简单的文字查找和替换。 @Zacky1 你不需要取消任何东西。正如我在回答中指出的那样,您的代码完美地工作,因为它成功地删除了美元符号;只是无缘无故,两行后你又把美元符号放回去了。
    • 是的,但我想显示美元符号...如果有更简单的方法可以确保美元符号后面的数字是整数,把它扔给我哈哈...我只是不'不明白为什么它总是在寻找一个组,即使我使用转义序列(或将其用作字符串)......顺便说一句,它说错误是@m.appendReplacement(...)
    【解决方案2】:

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

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

    这是因为\u0024 没有 转义任何关于 appendReplacement 的内容,因为转义序列是在编译时解析的。在运行时,源中写入"\u0024" 的字符串长度为1,其唯一字符是文字​​美元符号。 (事实上​​,Unicode 转义序列几乎是 Java 编译器在计算行数之后首先解析的内容。例如,您可以声明一个变量 int $foo;,然后在代码中(正则表达式甚至字符串之外)使用它 @ 987654329@(或\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));
    

    【讨论】:

      【解决方案3】:

      按照您的编码替换和解析,对我有用。 String.replace(String,String) 不会将参数视为正则表达式。如果您想将正则表达式作为参数传递,请使用 String.replaceAll(String,String) 或 String.replaceFirst(String,String)。

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

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

      如果您想替换每个$ 登录w,请使用w.replace("$", "")。在这里,"$" 不被视为正则表达式。

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

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

      【讨论】:

        猜你喜欢
        • 2018-01-15
        • 1970-01-01
        • 2021-07-13
        • 2012-08-29
        • 2022-12-02
        • 1970-01-01
        • 2012-09-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多