1

IMAP応答から出てくる括弧で囲まれたリストをPythonリストまたはタプルに分割する簡単な方法を探しています。から行きたい

'(BODYSTRUCTURE ("text" "plain" ("charset" "ISO-8859-1") NIL NIL "quoted-printable" 1207 50 NIL NIL NIL NIL))'

(BODYSTRUCTURE, ("text", "plain", ("charset", "ISO-8859-1"), None, None, "quoted-printable", 1207, 50, None, None, None, None))
4

3 に答える 3

6

pyparsingのnestedExprパーサー関数は、デフォルトでネストされた括弧を解析します。

from pyparsing import nestedExpr

text = '(BODYSTRUCTURE ("text" "plain" ("charset" "ISO-8859-1") NIL NIL "quotedprintable" 1207 50 NIL NIL NIL NIL))'

print nestedExpr().parseString(text)

プリント:

[['BODYSTRUCTURE', ['"text"', '"plain"', ['"charset"', '"ISO-8859-1"'], 'NIL', 'NIL', '"quoted printable"', '1207', '50', 'NIL', 'NIL', 'NIL', 'NIL']]]

これはわずかに変更されたパーサーで、整数文字列から整数への解析時の変換、「NIL」からNoneへの変換、および引用符で囲まれた文字列からの引用符の削除を行います。

from pyparsing import (nestedExpr, Literal, Word, alphanums, 
    quotedString, replaceWith, nums, removeQuotes)

NIL = Literal("NIL").setParseAction(replaceWith(None))
integer = Word(nums).setParseAction(lambda t:int(t[0]))
quotedString.setParseAction(removeQuotes)
content = (NIL | integer | Word(alphanums))

print nestedExpr(content=content, ignoreExpr=quotedString).parseString(text)

プリント:

[['BODYSTRUCTURE', ['text', 'plain', ['charset', 'ISO-8859-1'], None, None, 'quoted-printable', 1207, 50, None, None, None, None]]]
于 2010-10-20T05:43:12.943 に答える
1

ネストされたタプルがあるという事実は、正規表現ではこれを不可能にします。括弧内にあるかどうかを示すパーサーを作成する必要があります。

あなたは試すことができます

tuple('(BODYSTRUCTURE ("text" "plain" ("charset" "ISO-8859-1") NIL NIL "quoted-printable" 1207 50 NIL NIL NIL NIL))'.replace("NIL", "None").split(' '))

編集:まあ、私はあなたの例でうまくいくものを手に入れました、しかしそれがあなたが望むものであるかどうかはわかりません。

BODYSTRUCTUREはどこかで定義する必要があります。

eval(",".join([a for a in '(BODYSTRUCTURE ("text" "plain" ("charset" "ISO-8859-1") NIL NIL "quoted-printable" 1207 50 NIL NIL NIL NIL))'.replace("NIL", "None").split(' ')]))

于 2010-10-20T00:51:07.013 に答える
1

実際に体の構造を含むサーバー回答の内部部分のみを取り出す:

struct = ('(((("TEXT" "PLAIN" ("CHARSET" "ISO-8859-1") NIL NIL "7BIT" 16 2)'
         '("TEXT" "HTML" ("CHARSET" "ISO-8859-1") NIL NIL "QUOTED-PRINTABLE"'
         ' 392 6) "ALTERNATIVE")("IMAGE" "GIF" ("NAME" "538.gif") '
         '"<538@goomoji.gmail>" NIL "BASE64" 172)("IMAGE" "PNG" ("NAME" '
         '"4F4.png") "<gtalk.4F4@goomoji.gmail>" NIL "BASE64" 754) "RELATED")'
         '("IMAGE" "JPEG" ("NAME" "avatar_airbender.jpg") NIL NIL "BASE64"'
         ' 157924) "MIXED")')

次のステップは、いくつかのトークンを置き換えることです。Pythonタイプに変換するために文字列を事前にペアリングします。

struct = struct.replace(' ', ',').replace(')(', '),(')

組み込みのモジュールコンパイラを使用して構造を解析します。

import compiler
expr = compiler.parse(struct.replace(' ', ',').replace(')(', '),('), 'eval')

式を変換するための単純な再帰関数の実行:

def transform(expression):
    if isinstance(expression, compiler.transformer.Expression):
        return transform(expression.node)
    elif isinstance(expression, compiler.transformer.Tuple):
        return tuple(transform(item) for item in expression.nodes)
    elif isinstance(expression, compiler.transformer.Const):
        return expression.value
    elif isinstance(expression, compiler.transformer.Name):
        return None if expression.name == 'NIL' else expression.name

そして最後に、ネストされたpythonタプルとして目的の結果が得られます。

result = transform(expr)
print result

(((('TEXT', 'PLAIN', ('CHARSET', 'ISO-8859-1'), None, None, '7BIT', 16, 2), ('TEXT', 'HTML', ('CHARSET', 'ISO-8859-1'), None, None, 'QUOTED-PRINTABLE', 392, 6), 'ALTERNATIVE'), ('IMAGE', 'GIF', ('NAME', '538.gif'), '<538@goomoji.gmail>', None, 'BASE64', 172), ('IMAGE', 'PNG', ('NAME', '4F4.png'), '<gtalk.4F4@goomoji.gmail>', None, 'BASE64', 754), 'RELATED'), ('IMAGE', 'JPEG', ('NAME', 'avatar_airbender.jpg'), None, None, 'BASE64', 157924), 'MIXED')

ボディ構造のさまざまなヘッダーを認識できる場所から:

text, attachments = (result[0], result[1:])
于 2011-09-29T11:34:23.770 に答える