2012-07-04 18 views
6

Gerçekten anlamadığım için JSON veya XML çıkışı yerine kullanmakta olduğum bir REST API'sı, yapılandırılmış bir metin biçimi kullanır. En basit şekliylePython (pyparsing) içinde yapılandırılmış bir metin dosyası ayrıştırma

SECTION_NAME entry other qualifying bits of the entry 
       entry2 other qualifying bits 
       ... 

olarak Bunlar yapısı görünse de, sekme ile sınırlandırılmış değildir, fakat bunun yerine boşlukla sınırlandırılmış ve eleme bit boşluklarla kelimeleri içerebilir. SECTION_NAME ile girişler arasındaki boşluk da 1'den birkaç (6 veya daha fazla) alana kadar değişkendir.

ENTRY  hsa04064     Pathway 
NAME  NF-kappa B signaling pathway - Homo sapiens (human) 
DRUG  D09347 Fostamatinib (USAN) 
      D09348 Fostamatinib disodium (USAN) 
      D09692 Veliparib (USAN/INN) 
      D09730 Olaparib (JAN/INN) 
      D09913 Iniparib (USAN/INN) 
REFERENCE PMID:21772278 
    AUTHORS Oeckinghaus A, Hayden MS, Ghosh S 
    TITLE  Crosstalk in NF-kappaB signaling pathways. 
    JOURNAL Nat Immunol 12:695-708 (2011) 
:

Ayrıca biçiminin bir bölümü şeklinde bir referans için

SECTION_NAME entry 
    SUB_SECTION more information 
    SUB_SECTION2 more information 

girişleri içerir, gerçek veri ekstraktı (bazı bölümleri çıkarılmıştır), yapı kullanımını göstermektedir

Bu garip formatı saner (JSON'a dönüştürülebilen bir sözlük) olarak ayrıştırmaya çalışıyorum, ne yapacağım konusunda emin değilim: mekânlarda kör olarak bölünme bir karışıklığa neden olur (ayrıca boşluklarla ilgili bilgileri de etkiler)) ve bir bölümün ne zaman başladığını nasıl anlayabildiğime emin değilim. ot. Metin manipülasyon iş için yeterli mi yoksa daha karmaşık yöntemler kullanmalı mıyım?

DÜZENLEME:

bu iş için pyparsing kullanmaya başladı ama kayıtlar beni karıştırır çoklu-hat, burada İLAÇ ile bir örnek: ilacın ilk 3 hatlarına uygulanan

from pyparsing import * 
punctuation = ",.'`&-" 
special_chars = "\()[]" 

drug = Keyword("DRUG") 
drug_content = Word(alphanums) + originalTextFor(OneOrMore(Word(
     alphanums + special_chars))) + ZeroOrMore(LineEnd()) 
drug_lines = OneOrMore(drug_content) 
drug_parser = drug + drug_lines 

örneğin, ben bir yanlış sonuç elde (\ n okunabilirliği kolaylaştırmak için fiili getiri dönüştürülür): Gördüğünüz gibi ben beklediğiniz süre

['DRUG', ['D09347', 'Fostamatinib (USAN) 
     D09348 Fostamatinib disodium  (USAN) 
     D09692 Veliparib (USAN']] 

sonraki girişleri, hep birlikte toplu olsun:

['DRUG', [['D09347', 'Fostamatinib (USAN)'], ["D09348", "Fostamatinib disodium (USAN)"], 
      ['D09692', ' Veliparib (USAN)']]] 
+0

Eğer boşluk üzerinde bölme denediniz, ancak bölünme sayısının sınırlandırılması:

Daha basit bir yaklaşım, örneğin girişi ile bölünür? – inspectorG4dget

+0

@ inspectorG4dget: Bunu düşündüm, ancak tek girişler değişken alan gereksinimine sahiptir (bu yüzden muhtemelen her bölüm kendi özel bölme sayısını gerektirir) – Einar

+0

Aha! O zaman belki de daha iyi bir seçim olurdu (http://docs.python.org/library/re.html#re.split) http://docs.python.org/library/re.html#re.split) daha iyi bir seçim olurdu – inspectorG4dget

cevap

3

Ayrıştırıcı tabanlı bir yaklaşım kullanmanızı öneririm. Örneğin, eldeki görev için Python PLY kullanılabilir. Eğer tespit edilen Son girişi kullanmalısınız, girişi olmadan hatlar için

m = re.compile('^ENTRY\s+(.*)$') 
m.search(line) 
if m: 
    m.groups()[0].strip() 

:

+0

Bunu ve Antonio Beamud'un çözümlerini kısa bir süre test edeceğim. Teşekkürler. – Einar

+2

@Einar Başka bir ayrıştırma seçeneği http://pyparsing.wikispaces.com/ olacak ve bu da makul belgelere ve çok sayıda örneğe sahip olacaktır. –

+0

Tek bir satıra ulaşmak, ancak çok satırlı sorun yaşamaya devam etmek için pıhtılaştırma ile bir deneme eklendi. – Einar

0

iyi yaklaşım gibi, normal ifadeler kullanmaktır.

vals = line.split('DRUG') 
if len(vals) > 1: 
    drug_field = vals[1].strip()