Pyparsing строка CSV со случайными кавычками

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

<118>date=2010-05-09,time=16:41:27,device_id=FE-2KA3F09000049,log_id=0400147717,log_part=00,type=statistics,subtype=n/a,pri=information,session_id=o49CedRc021772,from="prvs=4745cd07e1=example@example.org",mailer="mta",client_name="example.org,[194.177.17.24]",resolved=OK,to="example@example.org",direction="in",message_length=6832079,virus="",disposition="Accept",classifier="Not,Spam",subject="=?windows-1255?B?Rlc6IEZ3OiDg5fDp5fog+fno5fog7Pf46eHp7S3u4+Tp7SE=?="

Я пытался использовать модуль CSV, и он не соответствовал, вызвал, я не нашел способ проигнорировать то, что заключается в кавычки. Pyparsing был похож на лучший ответ, но я не нашел способ объявить все грамматики.

В настоящее время я использую свой старый сценарий Perl для парсинга его, но я хочу записанный в Python. если Вам будет нужен мой отрывок Perl, то я буду рад обеспечить его.

Любая справка ценится.

6
задан Thomas Wouters 9 May 2010 в 13:32
поделиться

2 ответа

Я не уверен, что вы действительно ищете, но

import re
data = "date=2010-05-09,time=16:41:27,device_id=FE-2KA3F09000049,log_id=0400147717,log_part=00,type=statistics,subtype=n/a,pri=information,session_id=o49CedRc021772,from=\"prvs=4745cd07e1=example@example.org\",mailer=\"mta\",client_name=\"example.org,[194.177.17.24]\",resolved=OK,to=\"example@example.org\",direction=\"in\",message_length=6832079,virus=\"\",disposition=\"Accept\",classifier=\"Not,Spam\",subject=\"=?windows-1255?B?Rlc6IEZ3OiDg5fDp5fog+fno5fog7Pf46eHp7S3u4+Tp7SE=?=\""
pattern = r"""(\w+)=((?:"(?:\\.|[^\\"])*"|'(?:\\.|[^\\'])*'|[^\\,"'])+)"""
print(re.findall(pattern, data))

дает вам

[('date', '2010-05-09'), ('time', '16:41:27'), ('device_id', 'FE-2KA3F09000049'),
 ('log_id', '0400147717'), ('log_part', '00'), ('type', 'statistics'),
 ('subtype', 'n/a'), ('pri', 'information'), ('session_id', 'o49CedRc021772'),
 ('from', '"prvs=4745cd07e1=example@example.org"'), ('mailer', '"mta"'),
 ('client_name', '"example.org,[194.177.17.24]"'), ('resolved', 'OK'),
 ('to', '"example@example.org"'), ('direction', '"in"'),
 ('message_length', '6832079'), ('virus', '""'), ('disposition', '"Accept"'),
 ('classifier', '"Not,Spam"'), 
 ('subject', '"=?windows-1255?B?Rlc6IEZ3OiDg5fDp5fog+fno5fog7Pf46eHp7S3u4+Tp7SE=?="')
]

Возможно, вы захотите потом очистить строки в кавычках. (с использованием mystring.strip ("'\" ") ).

РЕДАКТИРОВАТЬ : это регулярное выражение теперь также правильно обрабатывает экранированные кавычки внутри строк в кавычках ( a =" Она сказала \ " Привет! \ "" ).

Объяснение регулярного выражения:

(\w+)=((?:"(?:\\.|[^\\"])*"|'(?:\\.|[^\\'])*'|[^\\,"'])+)

(\ w +) : сопоставить идентификатор и записать его в обратную ссылку № 1

= : сопоставить =

(: Захватить следующее в обратную ссылку № 2:

(?: : Одно из следующих:

"(?: \\. | [^ \ \ "]) *" : двойная кавычка, за которой следует либо ноль, либо несколько следующих элементов: экранированный символ или символ без кавычек / обратной косой черты, за которым следует еще одна двойная кавычка

| : or

'(?: \\. | [^ \\']) * ': см. выше, только для одинарных кавычек.

| : или

{{1} }

[^ \\, "'] : один символ, который не является ни тем, ни другим обратная косая черта, запятая или кавычка.

) + : повторить хотя бы один раз, столько раз, сколько возможно.

) : конец группы захвата № 2.

5
ответ дан 9 December 2019 в 22:30
поделиться

Возможно, лучше использовать существующий синтаксический анализатор, чем использовать специальные регулярные выражения.

parse_http_list(s)
    Parse lists as described by RFC 2068 Section 2.

    In particular, parse comma-separated lists where the elements of
    the list may include quoted-strings.  A quoted-string could
    contain a comma.  A non-quoted string could have quotes in the
    middle.  Neither commas nor quotes count if they are escaped.
    Only double-quotes count, not single-quotes.

parse_keqv_list(l)
    Parse list of key=value strings where keys are not duplicated.

Пример:

>>> pprint.pprint(urllib2.parse_keqv_list(urllib2.parse_http_list(s)))
{'<118>date': '2010-05-09',
 'classifier': 'Not,Spam',
 'client_name': 'example.org,[194.177.17.24]',
 'device_id': 'FE-2KA3F09000049',
 'direction': 'in',
 'disposition': 'Accept',
 'from': 'prvs=4745cd07e1=example@example.org',
 'log_id': '0400147717',
 'log_part': '00',
 'mailer': 'mta',
 'message_length': '6832079',
 'pri': 'information',
 'resolved': 'OK',
 'session_id': 'o49CedRc021772',
 'subject':'=?windows-1255?B?Rlc6IEZ3OiDg5fDp5fog+fno5fog7Pf46eHp7S3u4+Tp7SE=?=',
 'subtype': 'n/a',
 'time': '16:41:27',
 'to': 'example@example.org',
 'type': 'statistics',
 'virus': ''}
6
ответ дан 9 December 2019 в 22:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: