разобрать неформатированную строку в словарь с python - PullRequest
2 голосов
/ 24 декабря 2010

У меня есть следующая строка.

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 (текст) вместо 'ДАТА: 12242010 Тип ключа: Nod32 Anti-Vir (30-дневная пробная версия) Ключ:a5B2s-sH12B-hgtY3-io87N-srg98-KLMNO 'Я получаю ошибку AttributeError: у объекта' NoneType 'нет атрибута' groups '

Что здесь не так?

Ответы [ 3 ]

1 голос
/ 24 декабря 2010

Если вы можете полагаться на одинаковые заголовки, то вам повезло.

>>> 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 голос
/ 24 декабря 2010
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

0 голосов
/ 24 декабря 2010
>>> 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}) соответствует дате (только цифры) и типу ключа (любые символы);затем он соответствует ключу, если он состоит из шести групп по пять буквенно-цифровых символов в каждой, разделенных черточками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...