代码之家  ›  专栏  ›  技术社区  ›  whydoihavetochoseaname

由于以下原因获取非法组引用$

  •  0
  • whydoihavetochoseaname  · 技术社区  · 6 月前

    我有一个函数,它应该替换简单的组合(例如: &a &c &b &l )聊天解释器可以理解和解析的东西( <color:green> 等等)

    但当处理类似的事情时 &a$&e%price% 我收到一个非法组引用错误

    我先处理价格替换!

    这是我的代码:

    public class Chat {
    
        private static final Pattern PATTERN = Pattern.compile("([^\\\\]?)&([0-9a-fk-r])");
    
        private static final Map<String, String> COLOR_CODES = new HashMap<>() {{
            put("0", "<reset><color:black>");
            put("1", "<reset><color:dark_blue>");
            put("2", "<reset><color:dark_green>");
            put("3", "<reset><color:dark_aqua>");
            put("4", "<reset><color:dark_red>");
            put("5", "<reset><color:dark_purple>");
            put("6", "<reset><color:gold>");
            put("7", "<reset><color:gray>");
            put("8", "<reset><color:dark_gray>");
            put("9", "<reset><color:blue>");
            put("a", "<reset><color:green>");
            put("b", "<reset><color:aqua>");
            put("c", "<reset><color:red>");
            put("d", "<reset><color:light_purple>");
            put("e", "<reset><color:yellow>");
            put("f", "<reset><color:white>");
            put("k", "<obfuscated>");
            put("l", "<bold>");
            put("m", "<strikethrough>");
            put("n", "<underlined>");
            put("o", "<italic>");
            put("r", "<reset>");
        }};
    
        public static Component translate(String text) {
            // Then apply color codes
            return Colors.interprate(replaceprimitive(text.replaceAll(String.valueOf(LegacyComponentSerializer.SECTION_CHAR), "&")));
        }
    
        private static String replaceprimitive(String string) {
            return PATTERN.matcher(string).replaceAll(matchResult -> matchResult.group(1) + COLOR_CODES.get(matchResult.group(2)));
        }
    }
    

    我这样称呼它:

    sender.send(Chat.translate("&c$&e%test%".replaceAll("%test%", "100")));
    

    请注意,如果$和数字之间没有简单的代码,则不会出现此问题。例如: &c$%test% 不会引起任何问题,但是 $&l%test%

    我曾尝试使用Matcher.quotePlacement,甚至尝试手动完成并替换 $ \\$ 但什么都没用。

    注:占位符 %price% 在进入功能之前需要更换

    1 回复  |  直到 6 月前
        1
  •  5
  •   gwcoffey    6 月前

    你的问题在于你传递给的lambda表达式 #replaceAll 在这里:

    matchResult ->    
       matchResult.group(1) + 
       COLOR_CODES.get(matchResult.group(2));
    

    结果 matchResult.group(1) 有时 $ 你想把它解释成字面意思 $ 替换为字符串,但是 $ 在匹配器中很特别 as documented here 你需要避开任何字面意思 $ \ 在lambda返回的替换字符串中。

    您可以使用 Matcher.quoteReplacement(...) 方法 documented here .

    以下是您代码的固定版本:

     private static final Map<String, String> COLOR_CODES = new HashMap<>() {{
            put("0", "<reset><color:black>");
            put("1", "<reset><color:dark_blue>");
            put("2", "<reset><color:dark_green>");
            put("3", "<reset><color:dark_aqua>");
            put("4", "<reset><color:dark_red>");
            put("5", "<reset><color:dark_purple>");
            put("6", "<reset><color:gold>");
            put("7", "<reset><color:gray>");
            put("8", "<reset><color:dark_gray>");
            put("9", "<reset><color:blue>");
            put("a", "<reset><color:green>");
            put("b", "<reset><color:aqua>");
            put("c", "<reset><color:red>");
            put("d", "<reset><color:light_purple>");
            put("e", "<reset><color:yellow>");
            put("f", "<reset><color:white>");
            put("k", "<obfuscated>");
            put("l", "<bold>");
            put("m", "<strikethrough>");
            put("n", "<underlined>");
            put("o", "<italic>");
            put("r", "<reset>");
        }};
    
        public static Component translate(String text) {
            // Then apply color codes
            return Colors.interprate(replaceprimitive(text.replaceAll(String.valueOf(LegacyComponentSerializer.SECTION_CHAR), "&")));
        }
    
        private static String replaceprimitive(String string) {
            return PATTERN.matcher(string).replaceAll(matchResult ->
              Matcher.quoteReplacement(matchResult.group(1) + COLOR_CODES.get(matchResult.group(2))));
        }
    }