Reputation: 541
What is the best way to convert this format of string to object?
[Start successful - User:Berord; Name:Test; Fruits:Orange; Version:;]
I'm thinking to split it with ';' and do substring(str.indexOf("User:") + 1 ), substring(str.indexOf("Name:") + 1 )
It is still have any other better method?
Upvotes: 0
Views: 193
Reputation: 18568
I would go step by step splitting this String
:
-
) in order to access the interesting part only;
) to get the key-value pairs:
) to get the key and the value separatelyAs someone already mentioned in a comment, you can use a Map<String, String>
to store the key-value pairs.
There are several optimizations done in the following code, such as trim()
to eliminate leading and trailing whitespaces from keys and values, some (possibly obsolete) checks for existence of a key in the map and some checks for the results of splitting operations.
Here is an example solution, read the comments:
public static void main(String args[]) {
String s = "Start successful - User:Berord; Name:Test; Fruits:Orange; Version:;";
// provide a data structure that holds the desired key-value pairs
Map<String, String> kvMap = new HashMap<>();
// (#1) split the input by minus ('-') to get rid of the leading part
String[] splitByMinus = s.split("-");
// check if the result length is the expected one
if (splitByMinus.length == 2) {
// (#2) take the desired part and split it again, this time by semicolon (';')
String[] splitBySemicolon = splitByMinus[1].split(";");
for (String ss : splitBySemicolon) {
// (#3) split the result of the splitting by semicolon another time, this time
// by a colon (':')
String[] splitByColon = ss.split(":");
// again, check the length of the result
if (splitByColon.length == 2) {
// if yes, you have successfully extracted the key and value, erase leading and
// trailing spaces
String key = splitByColon[0].trim();
String value = splitByColon[1].trim();
// check if the map contains the key
if (kvMap.containsKey(key)) {
// YOU DECIDE: skip this entry or update the existing key with the new value
System.out.println("There already is a key " + key + ". What now?");
} else {
// if the map doesn't have the key, insert it along with the value
kvMap.put(key, value);
}
} else if (splitByColon.length == 1) {
System.out.println(
"There was a key or value missing the corresponding key or value: \""
+ splitByColon[0].trim()
+ "\" (splitting by colon resulted in only one String!)");
// for the moment, we regard this case as a key without a value
String key = splitByColon[0].trim();
// check if the map contains the key
if (kvMap.containsKey(key)) {
// YOU DECIDE: skip this entry or update the existing key with the new value
System.out.println("There already is a key " + key
+ ". What now? This time there is no new value, "
+ "so skipping this entry seems a good idea.");
// do nothing...
} else {
// if the map doesn't have the key, insert it along with the value
kvMap.put(key, null);
}
} else {
System.err.println("Splitting by colon resulted in an unexpected amount of Strings,"
+ "here " + splitByColon.length);
}
}
} else {
System.err.println("Splitting the input String resulted in an unexpected amount of parts");
}
// finally print your results that are stored in the map:
kvMap.forEach((key, value) -> System.out.println(key + " : " + (value == null ? "" : value)));
}
The result I get from it is
There was a key or value missing the corresponding key or value: "Version" (splitting by colon resulted in only one String!)
User : Berord
Version :
Name : Test
Fruits : Orange
Upvotes: 1
Reputation: 88707
If the user data always is in the form FieldNameWithoutSpaces:DataWithOutSemicolon; you could use the following regex along with Pattern and Matcher: (\S+):([^;]*); and extract groups 1 and 2 from each match.
Example:
Pattern p = Pattern.compile("(\\S+):([^;]*);");
Matcher m= p.matcher( "[Start successful - User:Berord; Name:Test; Fruits:Orange; Version:;]" );
while( m.find() ) {
String key = m.group( 1 );
String value = m.group( 2 );
//put those into a map or use in some other way, for demonstration I'll print them
System.out.println( key + "::" + value );
}
This would result in the following output.
User::Berord
Name::Test
Fruits::Orange
Version::
Note that the key should not contain whitespace but should be preceeded by at least one, otherwise you'd match much more, i.e. if your input was [Start successful-User:Berord;Name:Test;Fruits:Orange; Version:;]
you'd get key = " successful-User:Berord;Name:Test;Fruits"
andvalue = "Orange"
. In the same way your values should not contain semicolons or the matches would get messed up as well.
If you have the requirement that spaces need to be optional and values could contain semicolons the regex might get a lot more complex (depends on the requirements) or even unsuitable at all - in which case you'd need to use (write) a more specialized parser.
Upvotes: 1
Reputation: 1518
Split with ; first you will get array of string with size of 3 and you can loop them over and split that with :
String s = "Start successful - User:Berord; Name:Test; Fruits:Orange; Version:;".replace("Start successful -","");
String splits[]=s.split(";");
for(String split:splits)
{
String splittedStrings[] =split.split(":");
String key = splittedStrings[0];
String value = splittedStrings[1];
}
Upvotes: 0