2012-11-30 11 views
5

पायथन शौकिया में नए टेक्स्ट दस्तावेज़ को लिखें। मेरे पास एक टेक्स्ट फ़ाइल है जो हजारों लाइनों पर जानकारी सूचीबद्ध करती है और मैं एक रेखा का चयन करने की कोशिश कर रहा हूं और निम्नलिखित 2-3 लाइनों को एक पैटर्न से मेल खाने के आधार पर चुन रहा हूं। मैं फ़ाइल नीचे मूल में से हटा दिए गए हैं बस मुझे के हित के लिए फ़ाइल के कुछ हिस्सों को रोकने के लिए तो मेरे वर्तमान फ़ाइल इस तरह दिखता है:एक txt दस्तावेज़ की कई पंक्तियों को चुनने के साथ समस्या और पाइथन

trig1.RESP: 
stim4: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
trig1.RESP: 
trig1.RESP: 
trig5.RESP: 1 
stim5: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
stim3: silence.wav 
trig1.RESP: 
stim5: silence.wav 
trig1.RESP: 
trig6.RESP: 1 

और इतने पर और आगे ... असल में क्या मैं करने की कोशिश कर रहा हूं हर पंक्ति को लिखना जिसमें लाइन के चुप्पी। वाव भाग और उसके बाद अगली दो पंक्तियां हैं। क्योंकि यह silence.wav लाइन और लाइन जो प्रतिक्रिया (भाग मैं सबसे अधिक दिलचस्पी रहा हूँ, एक प्रतिक्रिया से पहले trig1 है प्रिंट

parsed_output = open("name-of-file-to-be-written", "w") 
filtered_input = open("name-of-file-that-has-above-data", "r") 
for line in filtered_input: 
    if "silence.wav" in line and "trig1" in filtered_input.next(): 
     parsed_output.write(line) 
     parsed_output.write(filtered_input.next()) 
parsed_output.close() 

यह अधिकांश भाग के लिए ठीक काम करता है: मैं निम्नलिखित कोड का इस्तेमाल किया इस बिंदु पर कम महत्वपूर्ण है)। हालांकि इस मुद्दे को मैं में चलाने है जब लाइनों जाना:

stim3: silence.wav 
trig1.RESP: 
stim5: silence.wav 

के बाद से मेरी उत्पादन तो (trig1 लंघन के बाद अगली पंक्ति) stim3 (वर्तमान पंक्ति) और stim5 लिखेंगे, मैं इसे अगले पर ले जाता है लगता है "उत्तेजना: silence.wav" और stim5 को छोड़ देता है क्योंकि इसे लिखा गया था जब इसे पिछले कमांड में शामिल किया गया था। मुझे stim6.RESP: stim5 के बाद 1 चाहिए, लेकिन मेरा आउटपुट उस कारण से नहीं दिखाता है जिसका मैंने वर्णन किया था। क्या कोई तरीका है जिसे मैं उस उत्तेजना 5 पर छोड़ने के लिए नहीं प्राप्त कर सकता हूं?

क्षमा करें अगर यह वास्तव में लंबा था। आपका अग्रिम में ही बहुत धन्यवाद!

+0

छोटे sidenote: मैं आपको हमेशा खोले गए फाइलों के बारे में सुझाव दूंगा। ऐसा करने का सबसे अच्छा तरीका - 'साथ' कथन का उपयोग करना। – cleg

उत्तर

4

इस तरह कुछ कैसे? (पूरी तरह से अपरीक्षित)

count = 3 
for line in filtered_input: 
    if "silence.wav" in line: 
     count = 0 
    else: 
     count += 1 

    if count <= 2: 
     filtered_output.write(line) 

यह कल्पना नहीं है, लेकिन मुझे लगता है कि यह बहुत मजबूत होना चाहिए।

+0

ओह मेरी भलाई जो इतना आसान था। यह भी काम किया! धन्यवाद धन्यवाद धन्यवाद! – user1867442

1

एक संभव दृष्टिकोण ताकि आप एक बार में तीन लाइनों का ट्रैक रख सकते एक deque उपयोग करने के लिए होगा:

import collections 

parsed_output = open("name-of-file-to-be-written", "w") 
filtered_input = open("name-of-file-that-has-above-data", "r") 

window = collections.deque([None]*3, maxlen=3) 
for line in filtered_input: 
    window.append(line) 
    if 'silence.wav' in window[0]: 
     parsed_output.write(window[0]) 
     # only output next two lines if they don't also contain 'silence.wav' 
     if 'silence.wav' not in window[1]: 
      parsed_output.write(window[1]) 
      if 'silence.wav' not in window[2]: 
       parsed_output.write(window[2]) 
# following if/elif in case last or second to last line contain 'silence.wav' 
if 'silence.wav' in window[1]: 
    parsed_output.write(window[1]) 
    parsed_output.write(window[2]) 
elif 'silence.wav' in window[2]: 
    parsed_output.write(window[2]) 
parsed_output.close() 

आप Deque को maxlen पैरामीटर प्रदान है, तो आप अतिरिक्त तत्वों में जोड़ जब अंत एक तत्व दूसरे छोर से दूर पॉप है, उदाहरण के लिए:

>>> x = collections.deque([1, 2, 3], maxlen=3) 
>>> x 
deque([1, 2, 3], maxlen=3) 
>>> x.append(4) 
>>> x 
deque([2, 3, 4], maxlen=3) 
>>> x.append(5) 
>>> x 
deque([3, 4, 5], maxlen=3) 

यह आपको फ़ाइल पर पुनरावृति लेकिन पिछले 3 लाइनों है कि आप एक सुविधाजनक तरीके से पढ़ा है, किसी भी समयके पहले तत्व को बचाने के लिए अनुमति देता हैआपकी हालत से मेल खाता है, बस मिलान की गई रेखा को आउटपुट करें और निम्नलिखित दो जब तक वे आपकी हालत से मेल नहीं खाते हैं।

+0

यह चालाक है, लेकिन क्या यह दो पंक्तियों को दो बार नहीं लिखता है ?, यह भी सुनिश्चित करने के लिए कि लूप के अंत में एक चेक हो, यह सुनिश्चित करने के लिए कि दूसरी पंक्ति को दूसरी पंक्ति लिखना न पड़े। – mgilson

+0

बस उन मुद्दों को हल करने के लिए संपादित किया गया, मैं सवाल से नहीं कह सकता कि क्या डुप्लिकेट लाइनों को वांछित किया गया था या नहीं, लेकिन शायद वे वहां नहीं होना चाहिए। –

+0

कृपया मेरी (अब हटाई गई) टिप्पणी को नज़रअंदाज़ करें। यह गलत था। – mgilson

2

psuedocode को यह अनुवाद करने पर मेरे प्रयास का कहना है:

For each (Line) { 
     If Next Line is "Trig1" AND Current Line is "silence.wav" 
      Log it 
} 
## And We're Done 

आप Trig6 वंचित हो रहे हैं क्योंकि आप अगली पंक्ति है कि 'नहीं करता है के लिए पूछ रहे हैं (मुझे यहाँ सही करने के लिए स्वतंत्र महसूस) टी मौजूद नहीं है। क्या आप इसे फिर से लिख सकते हैं जहां आप आगे की तरफ पीछे की ओर संदर्भित करते हैं और क्या यह आपकी समस्या को ठीक करता है?

1

आपको वास्तव में नियमित अभिव्यक्तियों का उपयोग करना चाहिए (मॉड्यूल पुनः)
जब कोई ग्रंथों का विश्लेषण करना चाहता है तो यह अनिवार्य है।

देखें यह करने के लिए अनुमति देता है क्या:

import re 

ss = """trig1.RESP: 
stim4: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
trig1.RESP: 
trig1.RESP: 
trig5.RESP: 1 
stim5: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
stim3: silence.wav 
trig1.RESP: 
stim5: silence.wav 
trig1.RESP: 
trig6.RESP: 1 

stim777: silence.wav 
stim111: silence.wav 
trig1.RESP: 
trig6.RESP: 1 
trig1.RESP: 
trig6.RESP: 1""" 

pat = ('^(.+silence.wav.*)(?<!) *\n' 
     '(?:(?!.*silence.wav)(.*)(?<!) *\n)?' 
     '(?:(?!.*silence.wav)(.*)(?<!) *)?') 

RE = re.compile(pat,re.MULTILINE) 

for tugr in RE.findall(ss): 
    print tugr 

परिणाम

('stim4: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1') 
('stim5: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1') 
('stim3: silence.wav', 'trig1.RESP:', '') 
('stim5: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1') 
('stim777: silence.wav', '', '') 
('stim111: silence.wav', 'trig1.RESP:', 'trig6.RESP: 1') 

और फिर तुम क्या आप लाइनों

पैट के इन tuples के साथ करना चाहते हैं के रूप में इस्तेमाल एक स्ट्रिंग है एक regex परिभाषित करने के लिए एक पैटर्न।
आरई, एक संकलित regex है यह एक वस्तु जो तरीकों खोज, मैच, findall, आदि

कोष्ठक () एक समूह को परिभाषित किया गया है है।
एक समूह पाठ के कुछ हिस्सों को कैप्चर करता है। लेकिन (?: ) ऐसे समूह को परिभाषित करता है जो मेल खाने वाले पाठ के हिस्से को नहीं पकड़ता है। टेक्स्ट के हिस्से पर कार्य करना उपयोगी होता है, उदाहरण के लिए समूह के अंत में क्वालीफायर * या ? या + डालने के लिए।

जब तीसरी पंक्ति में 'silence.wav' है, तो यह बेजोड़ रहना चाहिए, और दूसरी पंक्ति में 'silence.wav' है, केवल पहली पंक्ति का मिलान होना चाहिए। यही कारण है कि पैटर्न में दो स्थानों में (?.*silence.wav) भाग है।

^ एक संकेत
^ 'स्ट्रिंग की शुरुआत'

re.MULTILINE का अर्थ है 'एक लाइन की शुरुआत' अर्थ ध्वज के साथ है भागों पैटर्न के (?<!) * वहाँ के अंत में खाली रिक्त स्थान पकड़ नहीं कर रहे हैं लाइनों।

एक पैटर्न में बिंदु . का अर्थ है 'किसी भी चरित्र', वामो चरित्र

\n 

और अन्य बिंदुओं, जिस पर मैं तुम्हें जवाब कर सकते हैं अगर आप की जरूरत को छोड़कर।

+0

सुझाव के लिए धन्यवाद। मुझे लगता है कि तुम भी सही हो। अगला कदम, नियमित अभिव्यक्ति सीखें। समझ गया। :) – user1867442

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