fork download
  1. #!/usr/bin/env python
  2. from ast import literal_eval
  3. from tokenize import generate_tokens, NAME, NUMBER, OP, STRING, ENDMARKER
  4.  
  5. def parse_key_value_list(text):
  6. def check(condition):
  7. if not condition:
  8. raise ValueError((state, token))
  9.  
  10. KEY, EQ, VALUE, SEP = range(4)
  11. state = KEY
  12. for token in generate_tokens(lambda it=iter([text]): next(it)):
  13. type, string = token[:2]
  14. if state == KEY:
  15. check(type == NAME)
  16. key = string
  17. state = EQ
  18. elif state == EQ:
  19. check(type == OP and string == '=')
  20. state = VALUE
  21. elif state == VALUE:
  22. check(type in {NAME, NUMBER, STRING})
  23. value = {
  24. NAME: lambda x: x,
  25. NUMBER: int,
  26. STRING: literal_eval
  27. }[type](string)
  28. state = SEP
  29. elif state == SEP:
  30. check(type == OP and string == ',' or type == ENDMARKER)
  31. yield key, value
  32. state = KEY
  33.  
  34. if __name__=="__main__":
  35. import sys
  36. for text in sys.stdin:
  37. print(dict(parse_key_value_list(text.strip())))
Success #stdin #stdout 0.04s 8496KB
stdin
age=12,name=bob,hobbies="games,reading",phrase="I'm cool!"
phrase='I\'m cool!'
phrase='I\',m cool!'
phrase="I'm \"cool\", I think..."
stdout
{'phrase': "I'm cool!", 'age': 12, 'name': 'bob', 'hobbies': 'games,reading'}
{'phrase': "I'm cool!"}
{'phrase': "I',m cool!"}
{'phrase': 'I\'m "cool", I think...'}