1

次の点を考慮してください。

import re
sequence = 'FFFFFF{7}FFFFFF'
patterns = [ ('([0-9a-fA-F]+)', 'Sequence'),
    ('(\\([0-9a-fA-F]+\\|[0-9a-fA-F]+\\))', 'Option'),
    ('({[0-9a-fA-F]+})', 'Range'),
    ('(\\[[0-9a-fA-F]+:([0-9a-fA-F]+|\*)\\])', 'Slice'),
    ('(\\?\\?)+', 'Byte_value_Wildcard'),
    ('(\\*)+', 'Byte_length_wildcard') ]
fragment_counter = 0
fragment_dict= {}
fragments_list = []
while sequence:
    found = False
    for pattern, name in patterns:
        m = re.match (pattern,sequence)
        if m:
            fragment_counter+=1
            m = m.groups () [0]
            fragment_dict["index"]=fragment_counter
            fragment_dict["fragment_type"]=name
            fragment_dict["value"]=m
            print fragment_dict
            fragments_list.append(fragment_dict)
            sequence = sequence [len (m):]
            found = True
            break
     if not found: raise Exception ('Unrecognized sequence')

print fragments_list

「print fragment_dict」行に到達するたびに、正しい(期待される)出力が得られます。

{'index': 1, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}
{'index': 2, 'fragment_type': 'Range', 'value': '{7}'}
{'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}

ただし、リスト項目 fragments_listは、期待どおりの各行ではなく、最終的な dict の 3 つのコピーです。

[{'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}, {'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}, {'index': 3, 'fragment_type': 'Sequence', 'value': 'FFFFFF'}]

これはappend、辞書の各反復をコピーするのではなく、辞書のインスタンスを参照しているためだと思います。関数を使用して見ましlist()たが、辞書アイテムでは、辞書キーのリストが表示されます。

私は何を間違っていますか?
私はデータ型に執着していません。見つけたフラグメントごとに 3 つのデータ要素 (そしておそらく 4 つ目) を保持する方法が必要でした。

4

2 に答える 2

3

あなたはとても近くにいます。list()任意のシーケンスからnew を生成する関数list(この場合、dictシーケンスとしての a はそのキーのシーケンスです) の代わりに、任意のマッピングからdict()new を生成する関数を使用します。dict

または、もっと単純に、copyメソッドを使用するだけです。

または、さらに単純に、fragment_dict= {}をループに移動するだけでdict、同じものを再利用し続けるのではなく、新しいものを作成できます。

于 2013-02-19T01:51:24.553 に答える
1

最後の質問に対する私の回答のコードを実際に使用していることを確認できてうれしいです。私の答えが実際に役立つとき、私はいつも幸せです.

前の質問で、この解析は解析されたトークンを後で処理するためのウォームアップにすぎないと述べたことを考慮して、次のように考えることができます。

所有しているトークン タイプごとにクラスを作成します。それらのそれぞれの中にメソッドを実装しprocessます。これは、実際の処理を行うことがあります (以下のコードで行うウルフ、ベアリング、キツネ、バッジの代わりに)。

次に、ストリーム全体をStreamクラスで解析します。を介してトークンを反復Stream.tokens処理し、 を呼び出すことで含まれるすべてのトークンを処理できますStream.process

これらのクラスを 1 つの Python ファイルに入れ、それをメイン コードにインポートすると、Streamそれを解析して処理するために のインスタンスを作成するだけで済みます。

このようなもの:

#! /usr/bin/python3.2

import re

class Sequence:
    def __init__ (self, raw): self.__raw = raw
    def __str__ (self): return 'Sequence {}'.format (self.__raw)
    def process (self): print ('Wolfing sequence {}'.format (self.__raw) )

class Option:
    def __init__ (self, raw): self.__raw = raw
    def __str__ (self): return 'Option {}'.format (self.__raw)
    def process (self): print ('Foxing option {}'.format (self.__raw) )

class Range:
    def __init__ (self, raw): self.__raw = raw
    def __str__ (self): return 'Range {}'.format (self.__raw)
    def process (self): print ('Bearing range {}'.format (self.__raw) )

class Slice:
    def __init__ (self, raw): self.__raw = raw
    def __str__ (self): return 'Slice {}'.format (self.__raw)
    def process (self): print ('Badgering slice {}'.format (self.__raw) )


class Stream:
    patterns = [ ('([0-9a-fA-F]+)', Sequence),
        ('(\\([0-9a-fA-F]+\\|[0-9a-fA-F]+\\))', Option),
        ('({[0-9a-fA-F]+})', Range),
        ('(\\[[0-9a-fA-F]+:[0-9a-fA-F]+\\])', Slice) ]

    def __init__ (self, stream):
        self.__tokens = []
        while stream:
            found = False
            for pattern, cls in self.patterns:
                m = re.match (pattern, stream)
                if m:
                    m = m.groups () [0]
                    self.__tokens.append (cls (m) )
                    stream = stream [len (m):]
                    found = True
                    break
            if not found: raise Exception ('Unrecognized sequence')

    @property
    def tokens (self): return (token for token in self.__tokens)

    def process (self):
        for token in self.__tokens: token.process ()

stream = Stream ('524946(46|58){4}434452[22:33]367672736E')
print ('These are the tokens:')
for idx, token in enumerate (stream.tokens):
    print ('{} at position {}.'.format (token, idx) )

print ('\nNow let\'s process them all:')
stream.process ()

これにより、次の結果が得られます。

These are the tokens:
Sequence 524946 at position 0.
Option (46|58) at position 1.
Range {4} at position 2.
Sequence 434452 at position 3.
Slice [22:33] at position 4.
Sequence 367672736E at position 5.

Now let's process them all:
Wolfing sequence 524946
Foxing option (46|58)
Bearing range {4}
Wolfing sequence 434452
Badgering slice [22:33]
Wolfing sequence 367672736E
于 2013-02-19T03:08:17.627 に答える