【问题标题】:java String replace charactersjava字符串替换字符
【发布时间】:2021-01-27 16:55:38
【问题描述】:

我需要你的帮助来解决一个棘手的问题。 我有一张如下的地图

Map<Integer, String> ruleMap = new HashMap<>();
ruleMap.put(1, "A");
ruleMap.put(12, "Test - 12");
ruleMap.put(1012, "Test Metadata 12 A");

我有一个规则,我在其中分离 id 并将它们收集到一个列表中。通过遍历列表,我将其 id 替换为 map 中的相应值。

代码:

String rule = "1 AND 12 OR 1012 AND 12 or 1012";

List < String > idList = new ArrayList < > ();

Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher(rule);
while (m.find()) {
    idList.add(m.group());
}
for (String id: idList) {
    if (ObjectUtils.isNonEmpty(ruleMap.get(Integer.parseInt(id)))) {
        rule = rule.replaceFirst(id, ruleMap.get(Integer.parseInt(id)));
    }
}
System.out.println(rule);

我得到这样的输出 -

A AND Test - Test - 12 OR Test Metadata 12 A AND 12 or Test Metadata 12 A

如您所见,id 12 的第一次迭代替换了其尊重的值,但在第二次出现 id 12 时,将值 Test - 12 替换为 Test - Test - 12

那么谁能帮我解决这个问题?

【问题讨论】:

    标签: java string replace split


    【解决方案1】:

    您需要使用正确的单词边界进行正则表达式替换。我建议使用正则表达式迭代器(正如您已经在做的那样),但使用模式 \b\d+\b 仅匹配完整的数字字符串。然后,在每次匹配时,在规则映射中进行查找(如果存在数字)以找到替换值。使用Matcher#appendReplacement 来构建替换字符串。

    Map<String, String> ruleMap = new HashMap<>();
    ruleMap.put("1", "A");
    ruleMap.put("12", "Test - 12");
    ruleMap.put("1012", "Test Metadata 12 A");
    
    String rule = "1 AND 12 OR 1012 AND 12 or 1012";
    
    Pattern pattern = Pattern.compile("\\b\\d+\\b");
    Matcher m = pattern.matcher(rule);
    StringBuffer buffer = new StringBuffer();
      
    while(m.find()) {
        if (ruleMap.containsKey(m.group(0))) {
            m.appendReplacement(buffer, ruleMap.get(m.group(0)));
        }
    }
    
    m.appendTail(buffer);
    
    System.out.println(rule + "\n" + buffer.toString());
    

    打印出来:

    1 AND 12 OR 1012 AND 12 or 1012
    A AND Test - 12 OR Test Metadata 12 A AND Test - 12 or Test Metadata 12 A
    

    【讨论】:

    • 如果您需要调试帮助,您至少需要在这里给我一些上下文。
    • 我认为我的规则映射包含任何导致此错误的特殊字符,如 $ 或 #% 或 ( )。
    • 我知道如何解决这个问题,但你现在问的是一个不同的问题。
    • 对不起,蒂姆,但你能告诉我是什么导致了这种错误吗?就像我检查过的一样,但我的规则映射中没有任何特殊字符。那么是否还有其他可能导致此错误?
    • 您需要使用Pattern#quote 对搜索词进行正则表达式转义。但同样,您在上面实际提出的问题仅搜索数字。如果您无法自行解决,我建议您提出一个新问题。
    【解决方案2】:

    如果您碰巧使用 Java 9 或更高版本,您也可以使用 Matcher#replaceAll

    Map<Integer, String> ruleMap = new HashMap<>();
    ruleMap.put(1, "A");
    ruleMap.put(12, "Test - 12");
    ruleMap.put(1012, "Test Metadata 12 A");
    
    String rule = "1 AND 12 OR 1012 AND 12 or 1012";
    
    rule = Pattern.compile("\\b\\d+\\b")
            .matcher(rule)
            .replaceAll(m -> ruleMap.getOrDefault(
                    Integer.parseInt(m.group()), m.group()));
    
    System.out.println(rule);
    

    【讨论】:

    • @TimBiegeleisen 感谢您指出这一点。我会添加Map.getOrDefault 来解决这个问题。
    猜你喜欢
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 2015-12-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2012-06-27
    相关资源
    最近更新 更多