用Python将未格式化字符串解析为字典

2 投票
3 回答
1949 浏览
提问于 2025-04-16 08:59

我有一个这样的字符串。

DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) Key: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO

我需要创建一个字典,格式应该像这样

{
    "DATE": "12242010",
    "Key Type": "Nod32 Anti-Vir (30d trial)",
    "Key": "a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO"
}

问题是这个字符串没有格式

DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) 
  • 日期和密钥类型之间没有空格
  • 另外,最好能对密钥进行一些验证,比如每个密钥框里有5个字符,以及框的数量

我刚开始学习python,尤其是正则表达式方面还很陌生。非常感谢。


这是我的代码。我是通过xpath获取字符串的。

为什么我不能在正则表达式中使用它呢?

import re
import lxml.html as my_lxml_hmtl
tree = my_lxml_hmtl.parse("test.html")
text = tree.xpath("string(//*[contains(text(),'DATE')])")
# this works
print re.match('DATE:\s+([0-9]{8})\s*Key Type:\s+(.+)\s+Key:\s+((?:[^-]{5}(?:-[^-]{5})*))', 'DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) Key: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO').groups()

# and this doesn't work, why?
ss = str(text)
# print ss gives the same string which worked in re fabove
print re.match('DATE:\s+([0-9]{8})\s*Key Type:\s+(.+)\s+Key:\s+((?:[^-]{5}(?:-[^-]{5})*))', ss).groups()

当我尝试用文本或str(text)代替 '日期: 12242010密钥类型: Nod32 Anti-Vir (30天试用) 密钥: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO'时,出现了一个错误 AttributeError: 'NoneType'对象没有属性'groups'

这里出了什么问题?

3 个回答

1

如果你能确保这些头部信息是一样的,那你就很幸运了。

>>> re.match('DATE:\s+([0-9]{8})\s*Key Type:\s+(.+)\s+Key:\s+((?:[^-]{5}(?:-[^-]{5})*))', 'DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) Key: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO').groups()
('12242010', 'Nod32 Anti-Vir (30d trial)', 'a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO')

不过,如果你觉得这些信息将来可能会改变,你可能需要在处理后再统计一下组的数量。

1
import re

def strToDict(inStr, keyList, sep=''):
    rxPieces = [pc + sep + '(.*?)' for pc in keyList]
    rx = re.compile(''.join(rxPieces) + '$')
    match = rx.match(inStr)
    return dict(zip(kl, match.groups()))

def isKey(inStr):
    rx = re.compile('(\w{5}-\w{5}-\w{5}-\w{5}-\w{5}-\w{5})')
    return (rx.match(inStr) is not None)

s = "DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) Key: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO"
res = strToDict(s, ['DATE','Key Type','Key'], ': ')

返回

{
    'DATE': '12242010',
    'Key': 'a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO',
    'Key Type': 'Nod32 Anti-Vir (30d trial) '
}

if isKey(res['Key']):
    print 'Found valid key'

返回 True

1
>>> import re
>>> regex = re.compile(r"DATE: (\d+)Key Type: (.*?) Key: ((?:\w{5}-){5}\w{5})")
>>> match = regex.match("DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) Key: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO")
>>> mydict = {"DATE": match.group(1),
...           "Key Type": match.group(2),
...           "Key": match.group(3)}
>>> mydict
{'DATE': '12242010', 'Key': 'a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO', 'Key Type': '
Nod32 Anti-Vir (30d trial)'}
>>>

这个正则表达式 DATE: (\d+)Key Type: (.*?) Key: ((?:\w{5}-){5}\w{5}) 用来匹配日期(只包含数字)和密钥类型(可以是任何字符)。接着,它会匹配一个密钥,这个密钥由六组每组五个字母或数字的字符组成,中间用短横线隔开。

撰写回答