2011-09-26 10 views
12

से फ़ाइल को पढ़ें और विशिष्ट लाइन संख्याओं के बारे में बात नहीं कर रहा हूं क्योंकि मैं एक ही प्रारूप के साथ कई फाइलें पढ़ रहा हूं लेकिन लंबाई में भिन्नता है।पायथन - टेक्स्ट

Something here... 
... ... ... 
Start      #I want this block of text 
a b c d e f g 
h i j k l m n 
End      #until this line of the file 
something here... 
... ... ... 

मुझे आशा है कि तुम्हें पता है मैं क्या मतलब है:
मैं इस पाठ फ़ाइल है कहो। मैं फ़ाइल के माध्यम से पुनरावृत्ति करने के बारे में सोच रहा था, फिर "स्टार्ट" और "एंड" की लाइन संख्या खोजने के लिए नियमित अभिव्यक्ति का उपयोग करके खोज करें, फिर स्टार्ट लाइन से एंड लाइन तक पढ़ने के लिए लाइनकेच का उपयोग करें। लेकिन लाइन नंबर कैसे प्राप्त करें? मैं किस काम का उपयोग कर सकता हूं?

+0

यह सवाल बहुत ही इस एक http://stackoverflow.com/questions/7098530/repeatedly-extract-a-line-between-two-delimiters-in-a-text-file-python – salomonvh

उत्तर

21

आप बस आरंभ और समाप्ति के बीच पाठ के ब्लॉक चाहते हैं, आप कुछ सरल की तरह कर सकते हैं:

with open('test.txt') as input_data: 
    # Skips text before the beginning of the interesting block: 
    for line in input_data: 
     if line.strip() == 'Start': # Or whatever test is needed 
      break 
    # Reads text until the end of the block: 
    for line in input_data: # This keeps reading the file 
     if line.strip() == 'End': 
      break 
     print line # Line is extracted (or block_of_lines.append(line), etc.) 

वास्तव में, आप डेटा को पढ़ने में में लाइन नंबर में हेरफेर करने की जरूरत नहीं है स्टार्ट एंड एंड मार्कर के बीच।

तर्क ("पढ़ा गया ...") दोनों ब्लॉक में दोहराया जाता है, लेकिन यह काफी स्पष्ट और कुशल है (अन्य तरीकों में आम तौर पर कुछ राज्य [ब्लॉक/ब्लॉक के ब्लॉक/अंत में पहुंचने के पहले] की जांच शामिल होती है, जो एक समय जुर्माना)।

1

यह आप के लिए एक शुरुआत होनी चाहिए:

started = False 
collected_lines = [] 
with open(path, "r") as fp: 
    for i, line in enumerate(fp.readlines()): 
     if line.rstrip() == "Start": 
      started = True 
      print "started at line", i # counts from zero ! 
      continue 
      if started and line.rstrip()=="End": 
      print "end at line", i 
      break 
      # process line 
      collected_lines.append(line.rstrip()) 

enumerate जनरेटर एक जनरेटर लेता है और पुनरावृत्तियों विश्लेषण करता है। ईजी।

print list(enumerate("a b c".split())) 

प्रिंट

[ (0, "a"), (1,"b"), (2, "c") ] 

अद्यतन:

पोस्टर "===" और लाइनों "======" मैच के लिए एक regex का उपयोग कर के लिए कहा:

import re 
print re.match("^=+$", "===")  is not None 
print re.match("^=+$", "======") is not None 
print re.match("^=+$", "=")  is not None 
print re.match("^=+$", "=abc") is not None 
print re.match("^=+$", "abc=") is not None 
3

यहां कुछ ऐसा काम करेगा जो काम करेगा:

data_file = open("test.txt") 
block = "" 
found = False 

for line in data_file: 
    if found: 
     block += line 
     if line.strip() == "End": break 
    else: 
     if line.strip() == "Start": 
      found = True 
      block = "Start" 

data_file.close() 
+0

के समान है यह एक साफ चाल है – BPm

+3

@ बीपीएम: यह "परिमित राज्य मशीन" (http://en.wikipedia.org/wiki/Finite_state_machine) का एक उदाहरण है: मशीन एक राज्य में शुरू होती है "ब्लॉक अभी तक नहीं मिला" (मिला == गलत), "ब्लॉक के भीतर" एक राज्य में चल रहा है (पाया == सही) और इस मामले में "अंत" मिलने पर रोकता है। वे थोड़ा अक्षम हो सकते हैं (यहां, 'पाए गए' को ब्लॉक में प्रत्येक पंक्ति के लिए चेक किया जाना चाहिए), लेकिन राज्य मशीनें अक्सर एक जटिल एल्गोरिदम के तर्क को स्पष्ट रूप से व्यक्त करने की अनुमति देती हैं। – EOL

+0

+1, क्योंकि यह पूरी तरह से मान्य राज्य मशीन दृष्टिकोण का एक अच्छा उदाहरण है। – EOL

2

आप आसानी से रेगेक्स का उपयोग कर सकते हैं। आप इसे जितना आवश्यक हो उतना मजबूत बना सकते हैं, नीचे एक साधारण उदाहरण है।

>>> import re 
>>> START = "some" 
>>> END = "Hello" 
>>> test = "this is some\nsample text\nthat has the\nwords Hello World\n" 
>>> m = re.compile(r'%s.*?%s' % (START,END),re.S) 
>>> m.search(test).group(0) 
'some\nsample text\nthat has the\nwords Hello' 
+0

+1: बहुत अच्छा विचार: यह कॉम्पैक्ट है, और यह बहुत ही कुशल हो सकता है, क्योंकि 'पुनः' मॉड्यूल तेज़ है। स्टार्ट और ईएनडी टैग को अपने आप से * लाइन पर होने के लिए मजबूर होना चाहिए, हालांकि, आपकी नियमित अभिव्यक्ति ('^ ... $') में। – EOL

+0

धन्यवाद:) .. मुझे नहीं लगता कि आप^|| का उपयोग कर सकते हैं $ जब आप पुनः उपयोग करते हैं।एस spec क्योंकि इसमें न्यूलाइन वर्ण शामिल हैं, आपको लगता है कि आपको स्पष्ट रूप से '% s \ n। *?% S \ n' – pyInTheSky

+1

कहना होगा कि आप निश्चित रूप से re.MULTILINE ध्वज जोड़कर, इस मामले में^... $ का उपयोग कर सकते हैं (http://docs.python.org/dev/library/re.html#module-contents)। – EOL

संबंधित मुद्दे