【问题标题】:parse unformatted string into dictionary with python使用python将未格式化的字符串解析为字典
【发布时间】:2011-05-30 08:45:31
【问题描述】:

我有以下字符串。

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) 
  • 在密钥类型之前的日期之后没有空格
  • 另外,最好对 Key 进行一些验证,例如,如果每个 key 框中有 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()

当我尝试使用 text 或 str(text) 而不是 'DATE: 12242010Key Type: Nod32 Anti-Vir (30d trial) Key: a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO' 我收到一个错误 AttributeError:“NoneType”对象没有属性“组”

这里有什么问题?

【问题讨论】:

  • 您是否总是有一个带有 DATE、Key Type 和 Key 的字符串,或者有时会有差异?
  • 日期、密钥类型和密钥始终存在

标签: python regex parsing


【解决方案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}) 匹配日期(仅限数字)和密钥类型(任何字符);如果它由六组每组五个字母数字字符组成,则它匹配一个键,用破折号分隔。

【讨论】:

    【解决方案2】:

    如果您可以依靠相同的标题,那么您就走运了。

    >>> 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')
    

    不过,如果您希望它发生变化,您可能必须在后处理中获取组数。

    【讨论】:

      【解决方案3】:
      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'
      

      返回真

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-13
        • 1970-01-01
        相关资源
        最近更新 更多