我有一个像这样的字符串:
*********** name: NOTINSTATE timestamp: 2015-09-16T12:33:01.253Z
MyKeyValue1 = myData MyKeyValue2 = 0.0 based on filter: no Filter
********************************
在此字符串中,我有 KeyValuePairs:
"name" NOTINSTATE
"timestamp" 2015-09-16T12:33:01.253Z
"MyKeyValue1" myData
"MyKeyValue2" 0.0
"based on filter" no Filter
我正在以相反的方式思考像 Freemarker 这样的东西,但我不认为 Freemarker 具有其他功能。
我知道我可以用一种肮脏的方式来做到这一点,并使用模式并分割字符串,但必须有更好的方法来做到这一点。
有什么有用的建议或框架吗? 我的searchString本身将来不会改变。它将永远是一样的。
最佳答案
正则表达式是你的 friend :
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]+" +
"\\*+";
关于java - 解析具有可变键值对的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32635129/