使用可变键值对解析字符串

时间:2015-09-17 16:10:13

标签: java string parsing

我有一个这样的字符串:

*********** name: NOTINSTATE timestamp: 2015-09-16T12:33:01.253Z 
MyKeyValue1 = myData MyKeyValue2 = 0.0 based on filter: no Filter
********************************

在这个String中我有KeyValuePairs:

"name" NOTINSTATE
"timestamp" 2015-09-16T12:33:01.253Z
"MyKeyValue1" myData
"MyKeyValue2" 0.0
"based on filter" no Filter

我正在以相反的方式思考像Freemarker这样的东西,但我认为Freemarker其他人没有这种功能。

我知道我可以在肮脏的方式上做它并使用模式并拆分String但是必须有更好的方法来做到这一点。

任何有用的建议或框架? 我的searchString本身将来不会改变。它将永远是相同的。

1 个答案:

答案 0 :(得分:2)

正则表达式是你的朋友:

String input = "*********** name: NOTINSTATE timestamp: 2015-09-16T12:33:01.253Z\n" +
               "MyKeyValue1 = myData MyKeyValue2 = 0.0 based on filter: no Filter\n" +
               "********************************";
String regex = "\\*+\\s+" +
               "(name):\\s+(.*?)\\s+" +
               "(timestamp):\\s+(.*?)\\s*[\r\n]+" +
               "(MyKeyValue1)\\s+=\\s+([^=]*)\\s+" +
               "(MyKeyValue2)\\s+=\\s+([^=]*)\\s+" +
               "(based on filter):\\s+(.*?)\\s*[\r\n]+" +
               "\\*+";
Matcher m = Pattern.compile(regex).matcher(input);
if (m.matches()) {
    Map<String, String> pairs = new LinkedHashMap<>();
    for (int i = 1; i <= 10; i += 2)
        pairs.put(m.group(i), m.group(i + 1));

    // print for testing
    for (Entry<String, String> entry : pairs.entrySet())
        System.out.printf("\"%s\" %s%n", entry.getKey(), entry.getValue());
}

输出正如您所示:

"name" NOTINSTATE
"timestamp" 2015-09-16T12:33:01.253Z
"MyKeyValue1" myData
"MyKeyValue2" 0.0
"based on filter" no Filter

<强>更新

上面的正则表达式在空格上是宽松的,但对键名称是严格的。你可以严格控制空格和宽松的键名或任何其他组合:

String regex = "\\*+ " +
               "(\\w+): (.+?) " +
               "(\\w+): (.+?)[\r\n]+" +
               "(\\w+) = ([^=]+?) " +
               "(\\w+) = ([^=]+?) " +
               "([^:]+): (.+?)[\r\n]+" +
               "\\*+";