Trying to create a dictionary from a given string which can be of the format
key1:value1 key2:value2
however picking value is a problem as sometimes it may have
- white spaces
key1: value1
- quotes
key1: "value has space"
Identifier for key is something:
Tried below
def tokenize(msg):
legit_args = [i for i in msg if ":" in i]
print(legit_args)
dline = dict(item.split(":") for item in legit_args)
return dline
above only works for no space values.
then tried below
def tokenize2(msg):
try:
#return {k: v for k, v in re.findall(r'(?=\S|^)(. ?): (\S )', msg)}
return dict(token.split(':') for token in shlex.split(msg))
except:
return {}
this works well with key:"something given like this"
but still needs some changes to work, below is the issue
>>> msg = 'key1: "this is value1 " key2:this is value2 key3: this is value3'
>>> import shlex
>>> dict(token.split(':') for token in shlex.split(msg))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: dictionary update sequence element #1 has length 1; 2 is required
>>> shlex.split(msg) # problem is here i think
['key1:', 'this is value1 ', 'key2:this', 'is', 'value2', 'key3:', 'this', 'is', 'value3']
CodePudding user response:
Would you please try something like:
import re
s = "key1: \"this is value1 \" key2:this is value2 key3: this is value3"
d = {}
for m in re.findall(r'\w :\s*(?:\w (?:\s \w )*(?=\s|$)|"[^"] ")', s):
key, val = re.split(r':\s*', m)
d[key] = val.strip('"')
print(d)
Output:
{'key3': 'this is value3', 'key2': 'this is value2', 'key1': 'this is value1 '}
Explanation of the regex:
\w :\s*
matches a word followed by a colon and possible (zero or more) whitespaces.(?: ... )
composes a non-capturing group.:\w (?:\s \w )*(?=\s|$)
matches one or more words followed by a whitespace or end of the string.- The pipe character
|
alternates the regex pattern. "[^"] "
matches a string enclosed by double quotes.