【问题标题】:parse string for key, value pairs with a known key delimiter使用已知的键分隔符解析键值对的字符串
【发布时间】:2018-07-31 14:35:27
【问题描述】:

如果关键字符串是具有明确分隔符的已知子字符串,我如何将字符串转换为字典?示例:

s = 'k1:text k2: more text k3:andk4: more yet'
key_list = ['k1','k2','k3']
(missing code)
# s_dict = {'k1':'text', 'k2':'more text', 'k3':'andk4: more yet'}  

在这种情况下,键必须以空格、换行符或字符串的第一个字符开头,并且必须(立即)后跟冒号,否则它们不会被解析为键。因此在示例中,k1k2k3 被读取为键,而k4k3 值的一部分。我还删除了尾随空格,但认为这是可选的。

【问题讨论】:

  • 键也可以在字符串的开头之前,除非该字符串的开头应该有一个空格。
  • @chrisz 啊,是的!我将编辑文本
  • @chrisz 我不知道你的意思...假设如果键字符串不是直接以空格开头(或其他例外情况)并且直接跟在冒号后面,它是一部分值(例如,问题中的 k4)

标签: python regex string dictionary


【解决方案1】:

您可以使用re.findall 来执行此操作:

>>> import re
>>> dict(re.findall(r'(?:(?<=\s)|(?<=^))(\S+?):(.*?)(?=\s[^\s:]+:|$)', s))
{'k1': 'text', 'k2': ' more text', 'k3': 'andk4: more yet'}

正则表达式需要一些反复试验。盯着它看够久,你就会明白它在做什么。

详情

(?:          
   (?<=\s)   # lookbehind for a space 
   |         # regex OR
   (?<=^)    # lookbehind for start-of-line
)     
(\S+?)       # non-greedy match for anything that isn't a space
:            # literal colon
(.*?)        # non-greedy match
(?=          # lookahead (this handles the third key's case)
   \s        # space  
   [^\s:]+   # anything that is not a space or colon
   :         # colon
   |
   $         # end-of-line
)

【讨论】:

  • 啊,谢谢 CS! :)
  • @ConfusinglyCuriousTheThird 不客气 ;-) 如果正则表达式在任何输入上失败,请告诉我。
猜你喜欢
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 2013-05-18
相关资源
最近更新 更多