在python中使用regex匹配令牌的可变出现次数

2024-10-02 18:20:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试多次匹配一个令牌,但我只得到最后一次出现的情况,我理解这是根据this answer的正常行为,但我无法获得示例中给出的解决方案。在

我的文字如下:

&{dict1_name}=   key1=key1value   key2=key2value
&{dict2_name}=   key1=key1value

所以基本上是多行,每行都有一个起始字符串,空格,然后是可变数量的密钥对。如果您想知道这是从哪里来的,那么这是一个robot框架变量文件,我正试图将其转换为python变量文件。在

我将每行迭代匹配密钥对,并从中构造一个python字典。在

我当前的regex模式是:

^{pr2}$

这可以正确地得到dict名称,但是密钥对只匹配最后出现的一个,如上所述。我如何让它返回一个包含:("dict1_name","key1","key1value"..."keyn","keynvalue")的元组,这样我就可以遍历它并构造python字典,如下所示:

dict1_name= {"key1": "key1value",..."keyn": "keynvalue"}

谢谢!在


Tags: 文件answername示例字典密钥情况解决方案
3条回答

您可以使用两个正则表达式一个用于名称,另一个用于项目,在第一个空格后应用一个:

import re

lines = ['&{dict1_name}=   key1=key1value   key2=key2value',
         '&{dict2_name}=   key1=key1value']

name = re.compile('^&\{(\w+)\}=')
item = re.compile('(\w+)=(\w+)')

for line in lines:
    n = name.search(line).group(1)
    i = '{{{}}}'.format(','.join("'{}' : '{}'".format(m.group(1), m.group(2)) for m in item.finditer(' '.join(line.split()[1:]))))
    exec('{} = {}'.format(n, i))
    print(locals()[n])

输出

^{pr2}$

说明

'^&\{(\w+)\}='匹配一个'&',后跟一个由大括号'\{', '\}'包围的单词{}。第二个regex匹配由'='连接的任何单词。行:

^{3}$

创建字典文本,最后使用exec创建具有所需名称的字典。您可以访问字典查询局部变量的值。在

结合听写理解使用两种表达方式:

import re

junkystring = """
lorem ipsum
&{dict1_name}=   key1=key1value   key2=key2value
&{dict2_name}=   key1=key1value
lorem ipsum
"""

rx_outer = re.compile(r'^&{(?P<dict_name>[^{}]+)}(?P<values>.+)', re.M)
rx_inner = re.compile(r'(?P<key>\w+)=(?P<value>\w+)')

result = {m_outer.group('dict_name'): {m_inner.group('key'): m_inner.group('value')
            for m_inner in rx_inner.finditer(m_outer.group('values'))}
            for m_outer in rx_outer.finditer(junkystring)}

print(result)

产生

^{pr2}$


这两个表达式是 ^{3}$

{见^ a1。第二个呢

(?P<key>\w+)=(?P<value>\w+)
# the key/value pairs

请参见a demo for the latter on regex101.com。在

剩下的就是在听写理解中对不同的表达方式进行简单的排序。在

正如您所指出的,您需要解决这样一个事实:捕获组只捕获最后一个匹配项。一种方法是利用文件中的行是iterable这一事实,并使用两种模式:一种用于“line name”,另一种用于其多个keyvalue对:*

import re

dname = re.compile(r'^&{(?P<name>\w+)}=')
keyval = re.compile(r'(?P<key>\w+)=(?P<val>\w+)')

data = {}
with open('input/keyvals.txt') as f:
    for line in f:
        name = dname.search(line)
        if name:
            name = name.group('name')
            data[name] = dict(keyval.findall(line))

*诚然,这有点低效,因为每行执行两次搜索。但对于中等大小的文件,应该没问题。

结果:

^{pr2}$

请注意,\w匹配Unicode单词字符。在


样本输入,keyvals.txt公司名称:

^{3}$

相关问题 更多 >