2012-03-07 7 views
1

を使用して文字列を爆発する方法はあります私は、文字列を持っている「パターン」

mylist = somefunction(mystring , pattern) 
print mylist 
--> {"Foo":"Bar (Titi)","Foo-age" : 50, "Airplanes": ["12:1","12:3",...], ...} 

これはPythonでも可能ですか?

いくつかのサンプルデータ[編集] - この1ビットが難しいかもしれないデリミタ/ W 5-COL CSVファイル ""

col-1,col-2,Path: 9876 (IGP) Local-Pref: 310000 MED: 0 Communities: 1234:6 1234:95 1234:101 1234:202 1234:500 1234:903 1234:3369 1234:8000 1234:8002 1234:16925 9876:19827 Next Hop: x.x.127.151 Originator ID: x.x.155.144 Cluster List: 0.0.29.99 0.0.29.97 0.0.26.245 0.0.2.179 ,col-4,col-5 

col-1,col-2,Path: 9876 (IGP) Local-Pref: 310000 MED: 0 Communities: 1234:3 1234:95 1234:101 1234:202 1234:13705 9876:19941 Next Hop: x.x.127.61 Originator ID: x.x.137.37 Cluster List: 0.0.29.99 0.0.29.97 0.0.1.195 ,col-4,col-5 

col-1,col-2,Path: 9876 (IGP) Local-Pref: 310000 MED: 0 Communities: 1234:2 1234:95 1234:101 Next Hop: x.x.127.149 Originator ID: x.x.137.29 Cluster List: 0.0.29.99 0.0.29.98 0.0.2.240 ,col-4,col-5 

col-1,col-2,Path: 9876 (IGP) Local-Pref: 310000 MED: 0 Communities: 1234:6 1234:95 1234:101 1234:202 1234:500 1234:903 1234:3369 1234:8000 1234:8002 1234:16924 9876:19827 Next Hop: x.x.127.151 Originator ID: x.x.155.144 Cluster List: 0.0.29.99 0.0.29.97 0.0.26.245 0.0.2.179 ,col-4,col-5 
+0

を私は正規表現を使用することができますが、私の文字列は、正確に、各ライン上の同じ書式(それはから来ていませんa "" "" csv "" "ファイル) – Franquis

+1

regexがそれをしないなら、あなたは1行でそれを行うことができるのか疑問です。おそらく、正規表現は必要なときに改行を無視することができるので、問題をより明確に説明する必要があります。あなたに困っているサンプルデータをいくつか表示してください。 – SpliFF

+1

私は、csvファイルに基づいたソリューションが直接的に簡単かもしれないと信じています。質問に例を追加できますか? – jcollado

答えて

2

これは2つのステップで実行できると思います。まず、フィールド名(Foo-Bar:)のようなものを探し、一致する前に「特別な」マーカー文字(例:@)を挿入します。第二に、あなたはパターンmarker field-name : dataを探し、データディクショナリを移入:

text = """ 
col-1,col-2,Path: 9876 (IGP) Local-Pref: 310000 MED: 0 Communities: 1234:6 1234:95 1234:101 1234:202 1234:500 1234:903 1234:3369 1234:8000 1234:8002 1234:16925 9876:19827 Next Hop: x.x.127.151 Originator ID: x.x.155.144 Cluster List: 0.0.29.99 0.0.29.97 0.0.26.245 0.0.2.179 ,col-4,col-5 
""" 

import re 

text = re.sub(r'([A-Z][A-Za-z -]+:)', r'@\1', text) 
data = {} 
for m in re.finditer(r'@(.+?):([^,@]+)', text): 
    data[m.group(1)] = m.group(2).strip() 

import pprint 
pprint.pprint(data) 

結果:

{'Cluster List': '0.0.29.99 0.0.29.97 0.0.26.245 0.0.2.179', 
    'Communities': '1234:6 1234:95 1234:101 1234:202 1234:500 1234:903 1234:3369 1234:8000 1234:8002 1234:16925 9876:19827', 
    'Local-Pref': '310000', 
    'MED': '0', 
    'Next Hop': 'x.x.127.151', 
    'Originator ID': 'x.x.155.144', 
    'Path': '9876 (IGP)'} 
+0

非常に興味深いアプローチ!その作品は完璧です – Franquis

1

以上を指定しますが、今、このソリューションで十分かのどちらかは、あなたが望むものに近いあなたを取得する必要がありますしてください:

mystring = "Foo: Bar (Titi) Foo-age: 50 Airplanes: 12:1 12:3 12:4 12:5 Next Hop: LAX Origine ID: 49 Hop List: 2 4 9 0 3" 
pattern = {"Foo", "Foo-age", "Airplanes", "Next Hop", "Origine ID", "Hop List"} 
to_list = {'Airplanes', 'Hop List'} 
def obtain_data(mystring, pattern, to_list):  
    result = {} 
    prev_pattern = None 
    prev_pos = 0 
    ordered_pattern = sorted(list(pattern), key=lambda x: mystring.find(x + ':')) 
    for p in ordered_pattern: 
     npos = mystring.find(p +':', prev_pos) 
     if prev_pattern is not None: 
      to_add = mystring[prev_pos+len(prev_pattern)+1 : npos].strip() 
      if prev_pattern in to_list: 
       to_add = to_add.split() 
      result[prev_pattern] = to_add 
     prev_pos = npos 
     prev_pattern = p 
    to_add = mystring[prev_pos+len(prev_pattern)+1 : len(mystring)].strip() 
    if prev_pattern in to_list: 
     to_add = to_add.split() 
    result[prev_pattern] = to_add 
    return result 

obtain_data(mystring, pattern, to_list) 

これは戻ります:

{'Foo-age': '50', 'Hop List': ['2', '4', '9', '0', '3'], 'Airplanes': ['12:1', '12:3', '12:4', '12:5'], 'Next Hop': 'LAX', 'Foo': 'Bar (Titi)', 'Origine ID': '49'} 

を私が最初にパターンを分類しています文字列のどこに表示されるかに応じてリストを作成します。

私はパターンの直後に「:」があると考えています。そうでない場合は、これを行うのが難しいことが分かります(あなたが示したFooとFoo-ageのように、別のパターンの接頭辞のパターンがあることを考慮すると)。

もう1つのことは、値の1つをリストにする場合は、その値をリストに変換して3番目のパラメータにするパターンを指定する必要があります。あなたがこれをいつもやっていると思わないなら、空のセットを提供することもできますが、これをスキップすることもできます。

最終編集:ケースでは、コードの上に表示されない場合がありますパターンを持って、あなただけの右のforループ

ordered_pattern = filter(lambda x: mystring.find(x) != -1, ordered_pattern) 

でソートされたリストの結果をフィルタリングすることができますうまくいけば、これはあなたによく役立つでしょう:)

関連する問題