Reputation: 458
I have a string like this:
*********** name: NOTINSTATE timestamp: 2015-09-16T12:33:01.253Z
MyKeyValue1 = myData MyKeyValue2 = 0.0 based on filter: no Filter
********************************
In this String i have the KeyValuePairs:
"name" NOTINSTATE
"timestamp" 2015-09-16T12:33:01.253Z
"MyKeyValue1" myData
"MyKeyValue2" 0.0
"based on filter" no Filter
I was thinking about something like Freemarker in reverse way but i don't think that Freemarker others this functionality.
I know i could do it on a dirty way and work with pattern and split the String but there must be a better way to do this.
Any suggestions or frameworks which would be useful? My searchString itself will not be changed in the future. It will be always the same.
Upvotes: 2
Views: 652
Reputation: 159215
A regular expression is your 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());
}
Output is exactly what you showed:
"name" NOTINSTATE
"timestamp" 2015-09-16T12:33:01.253Z
"MyKeyValue1" myData
"MyKeyValue2" 0.0
"based on filter" no Filter
Update
The above regex is lenient on spaces, but strict on key names. You could go strict on spaces and lenient on key names, or any other combination:
String regex = "\\*+ " +
"(\\w+): (.+?) " +
"(\\w+): (.+?)[\r\n]+" +
"(\\w+) = ([^=]+?) " +
"(\\w+) = ([^=]+?) " +
"([^:]+): (.+?)[\r\n]+" +
"\\*+";
Upvotes: 2