2

I am trying to parse an expression to find out some reserved operators/strings and replace them with corresponding numeric values , which are stored in a hashmap, and display the resultant expression which has numeric values instead of the reserved strings. This is what I am trying to do:

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" and "$2" are used to back reference the groups in the expression.

Here is the output of the same:

Exception in thread "main" java.lang.NullPointerException

whereas when I remove the fetching part (from the hashmap) and instead limit it to just a string change using the back-referenced groups, it works just fine.

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

Output:

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

I suspect that while fetching the value from the hashmap, the "$1" and "$2" variables have still not been resolved by back-referencing and hence, it is not able to locate a key corresponding to the same.

If this is true, then what method do you suggest to implement my use case where I need the replacement value from a predefined hashmap.

4

2 に答える 2

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

あなたの以前の例(昨日)から直接取られました

于 2012-10-26T13:03:38.873 に答える
1

2 番目の例が機能するのは、メソッドの有効な 2 番目の引数である isString.format("%s(%s)","$1","$2")の戻り値だからです。ただし、マップのメソッドに渡すと、が返されます。"$1($2)"replaceAll"$1($2)"getnull

これを機能させるには、マッチング、マッピング、および置換操作を分離する必要があると思います。

  • 正規表現のすべての一致のリストを取得します (正規表現一致の配列の作成を参照)。
  • マップから各一致の対応する数値を取得します。
  • replaceAll各試合で呼び出します。
于 2012-10-26T12:45:36.463 に答える