python 在字符串中值包含一个或多个空格的情况下,拆分每次出现的Key=Value对

dced5bon  于 2023-01-01  发布在  Python
关注(0)|答案(2)|浏览(196)

我有一个情况,用户可以输入命令与可选的键值对和值可能包含空格。
以下是4种不同形式用户输入,其中键和值用=号分隔,值用空格分隔:

"cmd=create-folder    name=SelfServe - Test ride"

"cmd=create-folder    name=SelfServe - Test ride server=prd"

"cmd=create-folder  name=cert - Test ride   server=dev site=Service"

"cmd=create-folder   name=cert - Test ride   server=dev site=Service permission=locked"

要求:我试图解析这个字符串,并根据字符串中的键和值将其拆分到字典中。
如果用户输入报表的第一种形式,则将生成如下字典:

query_dict = {

'cmd' : 'create-folder',
'name' : 'selfserve - Test ride'
}

如果用户输入将产生/添加附加键/值对的第二种形式的语句

query_dict = {

'cmd' : 'create-folder',
'name' : 'selfserve - Test ride',
'server' : 'prd'

}

如果用户输入第三种形式语句

query_dict ={

'cmd' : 'create-folder',
'name' : 'cert - Test ride',
'server' : 'dev',
'site': 'Service'
}

第四种形式产生字典与键/值分裂如下

query_dict ={

'cmd' : 'create-folder',
 'name' : 'cert - Test ride',
'server' : 'dev',
 'site': 'Service',
 'permission' : 'locked' }
  • 思想是解析一个字符串,其中键和值用=符号分隔,并且值可以有一个或多个空格,然后提取匹配的键/值对。
    我尝试了多种方法进行匹配,但无法找到一种通用正则表达式模式,该模式可以匹配/提取具有这种模式的任何字符串
    感谢你的帮助。
    我尝试了几种基于不同可能用户输入的模式Map,但这不是一种可伸缩的方法。例如:
    我创建了三个模式来匹配三种不同的用户输入,但是如果我能有一个通用模式来匹配字符串中key = value的任意组合,那就更好了(我在模式中硬编码了key,这并不理想
'(cmd=create-folder).*(name=.*).*' ,
    '(cmd=create-pfolder).*(name=.*).*(server=.*).*',
    '(cmd=create-pfolder).*(name=.*).*(server=.*).*(site=.*)'
vohkndzv

vohkndzv1#

我建议使用split,然后使用zip来为dict构造函数提供信息:

def get_dict(s):
    parts = re.split(r"\s*(\w+)=", s)
    return dict(zip(parts[1::2], parts[2::2]))

运行示例:

print(get_dict("cmd=create-folder    name=SelfServe - Test ride"))
print(get_dict("cmd=create-folder    name=SelfServe - Test ride server=prd"))
print(get_dict("cmd=create-folder  name=cert - Test ride   server=dev site=Service"))
print(get_dict("cmd=create-folder   name=cert - Test ride   server=dev site=Service permission=locked"))

输出:

{'cmd': 'create-folder', 'name': 'SelfServe - Test ride'}
{'cmd': 'create-folder', 'name': 'SelfServe - Test ride', 'server': 'prd'}
{'cmd': 'create-folder', 'name': 'cert - Test ride', 'server': 'dev', 'site': 'Service'}
{'cmd': 'create-folder', 'name': 'cert - Test ride', 'server': 'dev', 'site': 'Service', 'permission': 'locked'}

解释

使用此输入作为示例:

"cmd=create-folder    name=SelfServe - Test ride"

split正则表达式标识以下部分:

"cmd=create-folder    name=SelfServe - Test ride"
 ^^^^             ^^^^^^^^^

没有被它匹配的字符串最终会得到一个结果,所以我们有这些:

"", "create-folder", "SelfServe - Test ride"

第一个字符串是空的,因为它是第一个匹配项之前的字符串。
现在,由于正则表达式有一个捕获组,由该组捕获的字符串也会返回到结果列表中,位于 * odd * 索引处,因此parts的结果如下:

["", "cmd", "create-folder", "name", "SelfServe - Test ride"]

我们感兴趣的键出现在奇数索引处,我们可以用parts[1::2]得到,其中1是起始索引,2是步长。
这些键对应的 * values * 出现在 * even * 索引处,忽略索引0处的空字符串。因此,我们使用parts[2::2]获得这些值。通过调用zip,我们将这些键和值按照需要配对在一起。
最后,dict构造函数可以接受带有键/值对的参数,这正是zip调用所提供的。

wkyowqbh

wkyowqbh2#

尝试使用以下正则表达式:

(\S+)=([^=]+?)(?=\s\S+=|$)
    • 正则表达式解释**:
  • (\S+):第一组包含任何非空格字符
  • =:后跟等号
  • ([^=]+?):第二组包含任何不相等字符(最少可能)
  • (?=\s\S+=|$):后跟空格+单词+=或字符串结束字符

检查正则表达式演示here

    • 注意**:这里假设您的键(键对的右边)不允许空格。

然后可以使用下面的python代码来检索组:

import re

strings = [
    "cmd=create-folder    name=SelfServe - Test ride",
    "cmd=create-folder    name=SelfServe - Test ride server=prd",
    "cmd=create-folder  name=cert - Test ride   server=dev site=Service",
    "cmd=create-folder   name=cert - Test ride   server=dev site=Service permission=locked"
]

pattern = r'(\S+)=([^=]+?)(?=\s\S+=|$)'

for string in strings:
    print(string)
    for match in re.findall(pattern, string):
        print(f'Group1: {match[0]} \t Group2: {match[1]}')
    print()

查看python演示here

相关问题