-1

I am trying to convert the below type of string into Dictionary in Python.

'F1=Value1,F2=Value2,F3=[[F4=Value4,F5=Value5]],F6=Value6'

I would like to make the dictionary like:

{
    'F1': 'Value1', 
    'F2': 'Value2',
    'F3': '[[F4=Value4,F5=Value5]]',
    'F6': 'Value6'
}
Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
netbbq
  • 1
  • 1
    What have you tried? What's the problem you've run into? The ideal solution would be to [use JSON](https://docs.python.org/3/library/json.html) instead of an arbitrary format, but if that's not an option, you'll get better answers here if you show you're putting in the work but need a help with specific issues. – kungphu Nov 13 '18 at 06:31

1 Answers1

1

If you will continue to use the identical string format, you may use a complex regular expression to cover various patterns.

The following is a regular expression for a few patterns I have anticipated. Let me know if this solves your issue. If not, please provide details on where my solution fails:

Edit for explaining

  1. Group one (?=F\d+=\[).*?(\]){2,}(?=|,)
    • (?=F\d+=\[) match string begin with F, have one or more numbers, and have =[ after them
    • .*?(\]){2,} match string as less as it can, and it have 2 or more ] at the end
    • (?=|,) the string end , or nothing
  2. Group two F\d.[^,]+
    • after matching group one, it is easy to find the string like F6=Value6. because the first group takes precedence over the second group, so the second group can only match the remaining strings.

Code

string = "F1=Value1,F2=Value2,F3=[[F4=Value4,F5=Value5]],F6=Value6,F7=[[[BC],[AC]]]"
import re
resultset = [ele[0] if ele[0] else ele[-1] for ele in re.findall(r"((?=F\d+=\[).*?(\]){2,}(?=|,))|(F\d.[^,]+)",string)]
print({x[:x.find("=")]:x[x.find("=")+1:] for x in resultset})

Output

{'F6': 'Value6', 'F2': 'Value2', 'F3': '[[F4=Value4,F5=Value5]]', 'F1': 'Value1', 'F7': '[[[BC],[AC]]]'}

Edit: because the former regex does not work when string is F1=Value1,F2=Value2,F8=[iD=10,ig=12S],F3=[[F4=Value4,F5=Value5]],F6=Value6,F9=[iD=10,ig=12S],F7=[[[BC],[AC]]]

I changed regex to ((?=F\d+=\[).*?(\])+(?= |,F))|(F\d.[^,]+). And we need one trick. add one blankspace after string.

string = "F1=Value1,F2=Value2,F8=[iD=10,ig=12S],F3=[[F4=Value4,F5=Value5]],F6=Value6,F9=[iD=10,ig=12S],F7=[[[BC],[AC]]]"
import re
resultset = [ele[0] if ele[0] else ele[-1] for ele in re.findall(r"((?=F\d+=\[).*?(\])+(?= |,F))|(F\d.[^,]+)",string+" ")]
print({x[:x.find("=")]:x[x.find("=")+1:] for x in resultset})
KC.
  • 2,981
  • 2
  • 12
  • 22
  • @netbbq This is the victory of priority matching – KC. Nov 14 '18 at 05:17
  • Make your example a bit more complicated, you code doesn't work any more as below. "F1=Value1,F2=Value2,F8=[iD=10,ig=12S],F3=[[F4=Value4,F5=Value5]],F6=Value6,F9=[iD=10,ig=12S],F7=[[[BC],[AC]]]" – netbbq Nov 21 '18 at 18:54