使用String.replaceAll函数匹配正则表达式并从Java中的映射中获取替换值

时间:2012-10-26 12:16:56

标签: java regex str-replace

我正在尝试解析一个表达式以找出一些保留的运算符/字符串,并将它们替换为存储在散列映射中的相应数值,并显示具有数值而不是保留字符串的结果表达式。这就是我想要做的事情:

String expression = "SUM_ALL(4:5,5:6)>MAX(6:7)";
Map<String, Double> functionOperators = new HashMap<String,Double>();
functionOperators.put("SUM_ALL(4:5,5:6)", 4.0);
functionOperators.put("MAX(6:7)",5.0);

expression = expression.replaceAll("(SUM_ALL|MAX)\\s*\\(\\s*([\\d:,]+)\\s*\\)",
            Double.toString(functionOperators.get(String.format("%s(%s)","$1","$2"))));
System.out.println(expression);

“$ 1”和“$ 2”用于反向引用表达式中的组。

以下是相同的输出:

Exception in thread "main" java.lang.NullPointerException

然而,当我删除提取部分(来自hashmap),而是使用反向引用的组将其限制为只是字符串更改时,它可以正常工作。

expression = expression.replaceAll("(SUM_ALL|MAX)\\s*\\(\\s*([\\d:,]+)\\s*\\)",
            String.format("%s|%s|","$1","$2"));

输出:

SUM_ALL|4:5,5:6|>MAX|6:7|

我怀疑在从hashmap中获取值时,“$ 1”和“$ 2”变量仍然没有通过反向引用解析,因此,它无法找到与其对应的键。

如果这是真的,那么你建议用什么方法来实现我需要从预定义的hashmap中替换值的用例。

2 个答案:

答案 0 :(得分:2)

我不知道你有多少数据量,但似乎问题是replaceAll无法正常工作,因为我尝试过使用替换它并且工作得很棒。

String expression = "SUM_ALL(4:5,5:6)>MAX(6:7)<SUM_ALL(4:5,5:6)";
String mat = "";
Map<String, Double> functionOperators = new HashMap<String,Double>();
functionOperators.put("SUM_ALL(4:5,5:6)", 4.0);
functionOperators.put("MAX(6:7)",5.0);
Matcher m = 
    Pattern.compile(
            "(?:(SUM_ALL|MAX|MIN)\\(((?:\\d+:\\d+,?){1,2})\\)[+-><\\*/]?)")
            .matcher(expression);
while (m.find()) {
    mat = String.format("%s(%s)", m.group(1), m.group(2));
    expression = expression.replace(mat, functionOperators.get(mat).toString());
}
System.out.println(expression);

直接来自您之前的例子(昨天)

答案 1 :(得分:1)

您的第二个示例有效,因为String.format("%s(%s)","$1","$2")的返回值为"$1($2)",这是replaceAll方法的有效第二个参数。但是,当您将"$1($2)"传递给地图的get方法时,会返回null

为了完成这项工作,我认为您需要将匹配,映射和替换操作分开。

  • 获取正则表达式所有匹配项的列表(请参阅Create array of regex matches)。
  • 从地图中获取每个匹配的相应数值。
  • 在每场比赛中致电replaceAll