0

文字列があります。そのサンプルは次のようになります。

http://pastebin.com/2FFNa3Qx

パターンがあり、通常は "Sequence:" の後に次の 22 要素が繰り返されます。これらは分離したいデータです。

そこで、文字列Sequence:を 要素のリストに分割し、生成されたリストを を介してリストのリストに分割すると\n、長さが 22 要素のこれらのリストのそれぞれが必要なデータになると考えていました。だから私はこのコードでそれを試しました:

    proc = subprocess.Popen(cmd_rancli, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    //proc_stdout is the string
    proc_stdout  = proc.communicate(ran_opt_get_access_data)[0]

    parse = proc_stdout.split('Sequence:')
    print parse
    time.sleep(5)
    parse2 = [i.split('\n')[0] for i in parse] 
    print parse2
    time.sleep(5)

しかし、これらの2番目は私が期待するものを私に与えません.私は何が間違っていますか?

実際の出力:

    parse2 = ['RAN> get ap 108352 attr=4192', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' 
', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

スペースを分割して返す?

最初の解析結果の一部を次に示します: http://i.imgur.com/zhN3i3j.png

4

2 に答える 2

2

ペーストビンで提供した文字列を使用して( variable のコンテンツとしてa):

>>> result = [i.strip().split('\n') for i in a.split('Sequence')]
>>> [len(i) for i in result]
[10, 1, 3, 1, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 3, 1, 23, 23, 23]

たとえば、次のとおりです。

       Sequence:
     Value(int):     1
  Value(string):     2013-02-26T15:01:11Z
       Sequence:

それでは、23 個の要素を持つものだけをフィルタリングしましょう (最初の要素は であることに注意してください:)。

>>> result = [i[1:] for i in result if len(i) == 23]
>>> [len(i) for i in result]
[22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22]

これで、次のような配列ができました。

>>> print( '\n'.join(result[0]))
     Value(int):       10564
     Value(int):       13
     Value(int):       388
     Value(int):       0
     Value(int):       -321
     Value(int):       83
  Value(string):       272
  Value(string):       05
     Value(int):       67
     Value(int):       67
     Value(int):       708
     Value(int):       896
     Value(int):       31
     Value(int):       128
     Value(int):       -12
     Value(int):       -109
     Value(int):       0
     Value(int):       -20
     Value(int):       -111
     Value(int):       -1
     Value(int):       -1
     Value(int):       0

したがって、提供したデータで必要なコード全体は次のとおりです。

proc_stdout = proc.communicate(ran_opt_get_access_data)[0].decode('utf-8')
result = [i.strip().split('\n') for i in proc_stdout.split('Sequence')]
result = [i[1:] for i in result if len(i) == 23]
# Or at least [i[1:] for i in result if len(i) > 1]

編集 - 値の削除

単純なハックを使用するため、空白を削除するために常に:andが1 つしかありません。string.find()string.strip()

def filter_value(text):
    index = text.find( ':')
    # Not found :
    if index < 0:
        return text.strip()

    return text[index+1:].strip()

そして、次の行を置き換えて実装します。

result = [i[1:] for i in result if len(i) == 23]

このワンライナーで:

result = [[filter_value(j) for j in i[1:]] for i in result if len(i) == 23]
于 2013-04-15T15:16:31.370 に答える
1

期待した結果が得られないのは、それぞれSequence:の改行と次の改行の間に空白があるためです。[i.split('\n')[0] for i in parse]その空白になる改行で分割した後の最初のアイテムを取得します。

このアプローチを修正する代わりに、もう少し洗練された方法で出力をモデル化する dict を作成することをお勧めします。

def add_data(key, value, data):
    if key.startswith('Value('):
        if key.endswith('(int)'):
            value = int(value)
        data['Sequences'][-1].append(value)
    elif key == 'Sequence':
        data['Sequences'].append([])
    else:
        data[key] = value

def parse_lines(lineseq):
    data = {'Sequences':[]}
    for line in lineseq:
        try:
            key, value = [part.strip() for part in line.split(':', 1)]
        except ValueError:
            continue
        add_data(key, value, data)
    return data

lines = proc_stdout.split('\n')
data = parse_lines(lines)

これにより、次のようなデータ構造が生成されます。

{'AttributeId': '4192',
 'AttributeList': '',
 'ClassId': '1014 (AP)',
 'InstanceId': '0',
 'MessageType': '81 (GetAttributesResponse)',
 'ObjectInstance': '',
 'Protocol': 'BSMIS Rx',
 'RDN': '',
 'TransactionId': '66',
 'Sequences': [[],
               [1,'2013-02-26T15:01:11Z'],
               [],
               [10564,13,388,0,-321,83,'272','05',67,67,708,896,31,128,-12,-109,0,-20,-111,-1,-1,0],
               [10564,13,108,0,-11,83,'272','05',67,67,708,1796,31,128,-12,-109,0,-20,-111,-1,-1,0],
               [10589,16,388,0,-15,79,'272','05',67,67,708,8680,31,125,-16,-110,0,-20,-111,-1,-1,0],
               [10589,15,108,0,-16,81,'272','05',67,67,708,8105,31,126,-14,-109,0,-20,-111,-1,-1,0],
               [10637,40,233,0,-11,89,'272','03',30052,1,5,54013,33,103,-6,-76,1,-20,-111,-1,-1,0],
               [10662,46,234,0,-15,85,'272','03',30052,1,5,54016,33,97,-10,-74,1,-20,-111,-1,-1,0],
               [10712,51,12,0,-24,91,'272','01',4013,254,200,2973,3,62,-4,-63,0,-20,-111,-1,-1,0],
               [10737,15,224,0,-16,82,'272','01',3020,21,21,40770,33,128,-13,-108,0,-20,-111,-1,-1,0],
               [10762,14,450,0,-7,78,'272','01',3020,21,21,53215,29,125,-17,-113,0,-20,-111,-1,-1,0],
               [10762,15,224,0,-7,85,'272','01',3020,21,21,50770,33,128,-10,-105,0,-20,-111,-1,-1,0],
               [10762,14,124,0,-7,78,'272','01',3020,10,10,56880,32,128,-17,-113,0,-20,-111,-1,-1,0],
               [10812,11,135,0,-14,81,'272','02',36002,1,11,43159,31,130,-14,-113,1,-20,-111,-1,-1,0],
               [10837,42,23,0,-9,89,'272','02',36002,1,11,53529,31,99,-6,-74,1,-20,-111,-1,-1,0,54],
               [13,'2013-02-26T15:02:09Z'],
               [],
               [2,12,7,0,9,70,'272','02',20003,0,0,15535,0,0,0,0,1,100,100,-1,-1,0],
               [5,15,44,0,-205,77,'272','02',20003,0,0,15632,0,0,0,0,1,100,100,-1,-1,0],
               [7,25,9,0,0,84,'272','02',20002,0,0,50883,0,0,0,0,1,100,100,-1,-1,0]]
}

長さ 22 のシーケンスのみが必要な場合は、簡単に取得できます。

len22seqs = [s for s in data['Sequences'] if len(s)==22]
# alternatively:
len22seqs = filter(lambda s: len(s)==22, data['Sequences'])
于 2013-04-15T15:46:59.677 に答える