2009-06-08 11 views
4

HIすべてPython:テキストファイルの一部を読む

私はPythonとプログラミングには初めてです。私は大きなテキストファイルのチャンクで読み取る必要がある、形式は、次のようになります。私はformlemmapostag情報が必要

<word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head-"7" relation="ADV"/> 

。例えば上記のために私はhibernishibernus1およびn-p---nb-が必要です。

フォームに達するまで読むようにPythonに指示するには、引用符が"に達するまで前方に読むようにしてから、引用符"hibernis"の間の情報を読んでください。本当にこれで苦労します。

これまでのところ、句読点を削除し、文章を分割し、必要な情報をリストから取り除くことを試みました。しかし、全体のファイルを処理するためにPythonを取得するのに問題がある場合、私はこの作業を1行でしか行えません。私のコードは以下の通りです:

f=open('blank.txt','r') 
quotes=f.read() 
noquotes=quotes.replace('"','') 
f.close() 

rf=open('blank.txt','w') 
rf.write(noquotes) 
rf.close() 

f=open('blank.txt','r') 
finished = False 
postag=[] 
while not finished: 
    line=f.readline() 
    words=line.split() 
    postag.append(words[4]) 
    postag.append(words[6]) 
    postag.append(words[8])    
    finished=True 

は、任意のフィードバック/批判をお願い申し上げ

おかげ

答えて

2

私は正規表現モジュールを使用することをお勧めしたい:おそらく、これらの線に沿ってre

何か?

#!/usr/bin/python 
import re 

if __name__ == '__main__': 
    data = open('x').read() 
    RE = re.compile('.*form="(.*)" lemma="(.*)" postag="(.*?)"', re.M) 
    matches = RE.findall(data) 
    for m in matches: 
     print m 

これは<word ...>行がそれぞれ1行にし、各部分がその正確な順序であるとされていることを前提としていない、とあなたは完全なXML構文解析に対処する必要はありません。

+0

ありがとうretracile。ちょうどあなたのコードとその正確に私が必要としたものを試しました。本当に助けに感謝します。最初にreモジュールを試してみましたが、re.match( "|(f | 1)orm(。*)"行の場合は for f: の場合): 印刷>> rfformat、行、 –

+0

しかし、愚かにそのメソッドをあきらめて、リストメソッドに行った。 私はreモジュールを研究し、あなたのコードが何をしているのかを確認するつもりです –

+0

ありがとう、ありがとうございました –

1

ファイルは適切なXMLですか?その場合は、SAXパーサーを試してください:

import xml.sax 
class Handler (xml.sax.ContentHandler): 
    def startElement (self, tag, attrs): 
     if tag == 'word': 
      print 'form=', attrs['form'] 
      print 'lemma=',attrs['lemma'] 
      print 'postag=',attrs['postag'] 

ch = Handler() 
f = open ('myfile') 
xml.sax.parse (f, ch) 

(これはまったく正しいとは限りません)。通常の正規表現の答えに加えて

+0

こんにちは、ファイルはすべてXMLであり、サックスパーサーを見て、また下記の美しいスープを見なければなりません。 probは事をもっと簡単にしますか?あなたの助けをありがとう –

+0

BeautifulSoupは標準的なPythonディストリビューションには含まれていないことを覚えておいてください。パッケージを追加する権限を持たない環境でこのスクリプトを使用する必要がある場合に備えてください。 – eduffy

1

、これはXMLの形のように見えることから、あなたはBeautifulSoupのようなもの(http://www.crummy.com/software/BeautifulSoup/)を試してみてください

それは非常に使いやすいですし、HTMLのようなもので、タグ/属性を見つけます/ XMLを使用しています。一見の価値があるかもしれません。

0

xmlを手で解析するのは通常 です。あなたのコード は、いずれかの属性にエスケープされた の見積もりがある場合、壊れます。 xml パーサーから属性を取得する方が、おそらくクリーナーであり、エラーが発生する可能性は低くなります。

このようなアプローチでは、フォーマットに一致しない行がある場合は、ファイル全体の解析に問題が発生する可能性があります。あなたはこれに対処するか(

def parse (line): 
     try: 
      return parsed values here 
     except: 

のようなものをparselineメソッドを作成することによって、また、フィルタやマップ機能でこれを簡素化することができます。

lines = filter(lambda line: parseable(line), f.readlines()) 
values = map (parse, lines) 
0

ちょうどあなたの問題を強調するために:

finished = False 
counter = 0 
while not finished: 
    counter += 1 
    finished=True 
print counter 
+0

実際、あなたの答えは最高です。 :)他のすべての人は、コードを修正する気にしなかった。 – jacob

0

正規表現では、これが要点です(file.readline()の部分を実行できます):

import re 
line = '<word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head-"7" relation="ADV"/>' 
r = re.compile('form="([^"]*)".*lemma="([^"]*)".*postag="([^"]*)"') 
match = r.search(line) 
print match.groups() 

>>> 
('hibernis', 'hibernus1', 'n-p---nb-') 
>>> 
0

まず、ファイルの書き換えに多くの時間を費やさないでください。それは一般的に時間の無駄です。タグをクリーンアップして解析する処理は非常に速く、常にソースファイルから作業することができます。

source= open("blank.txt", "r") 
for line in source: 
    # line has a tag-line structure 
    # <word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head-"7" relation="ADV"/> 
    # Assumption -- no spaces in the quoted strings. 
    parts = line.split() 
    # parts is [ '<word', 'id="8"', 'form="hibernis"', ... ] 
    assert parts[0] == "<word" 
    nameValueList = [ part.partition('=') for part in parts[1:] ] 
    # nameValueList is [ ('id','=','"8"'), ('form','=','"hibernis"'), ... ] 
    attrs = dict((n,eval(v)) for n, _, v in nameValueList) 
    # attrs is { 'id':'8', 'form':'hibernis', ... } 
    print attrs['form'], attrs['lemma'], attrs['posttag'] 
+0

本当にここにevalが必要ですか? – SilentGhost

+0

@SilentGhost:これは他の状況のうち6つのうちの1つで、「eval is evil」と言いたい人もいます。しかし、この例の文字列が有効なPython文字列であると思われるのも偶然です。おそらくエスケープ文字がPythonと異なり、非Python文字列構文のためにevalを無効にしているかもしれません。 –

0

はすごい、君たちは高速です:)あなたは(と順序が知られている)、リストのすべての属性をしたい場合は は、その後、あなたはこのようなものを使用することができます

import re 
print re.findall('"(.+?)"',INPUT) 

INPUTがあるが

<word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head="7" relation="ADV"/> 

と印刷されたリストは、次のとおりです:ラインのような

['8', 'hibernis', 'hibernus1', 'n-p---nb-', '7', 'ADV'] 
5

それはXMLだ場合は、それを解析するためにElementTreeを使用します。各XML要素について

from xml.etree import ElementTree 

line = '<word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head="7" relation="ADV"/>' 

element = ElementTree.fromstring(line) 

を使用すると、簡単に名前とすべての属性を抽出することができます:あなたが持つ文書を持っているのであれば

>>> element.tag 
'word' 
>>> element.attrib 
{'head': '7', 'form': 'hibernis', 'postag': 'n-p---nb-', 'lemma': 'hibernus1', 'relation': 'ADV', 'id': '8'} 

word XML要素の束、このようなものがそれぞれ1から必要な情報を抽出します:

from xml.etree import ElementTree 

XML = ''' 
<words> 
    <word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head="7" relation="ADV"/> 
</words>''' 

root = ElementTree.fromstring(XML) 

for element in root.findall('word'): 
    form = element.attrib['form'] 
    lemma = element.attrib['lemma'] 
    postag = element.attrib['postag'] 

    print form, lemma, postag 

会社ファイル名が唯一の場合は、ではなく、parse()となります。

+0

これは素晴らしい解決策です: ) – jacob

+0

本当に役に立ちました、ありがとう:) –

関連する問題