2013-08-27 5 views
5

प्रश्न भाग 1पायथन: re.compile और re.sub

मैं इस फ़ाइल f1 मिला:

<something @37> 
<name>George Washington</name> 
<a23c>Joe Taylor</a23c> 
</something @37> 

और मैं इसे re.compile है कि यह इस f1 की तरह लग रहा हैं: (रिक्त स्थान के साथ)

George Washington Joe Taylor 

मैं इस कोड की कोशिश की लेकिन यह थोड़े हटाता है सब कुछ:

import re 
file = open('f1.txt') 
fixed = open('fnew.txt','w') 
text = file.read() 

match = re.compile('<.*>') 
for unwanted in text: 
    fixed_doc = match.sub(r' ',text) 

fixed.write(fixed_doc) 

मेरा अनुमान re.compile लाइन है लेकिन मुझे पूरा यकीन नहीं है कि इसके साथ क्या किया जाए। मुझे तीसरे पक्ष के एक्सटेंशन का उपयोग नहीं करना चाहिए। कोई विचार?

from collections import Counter 

def test(): 
    with open('f1.txt') as f: 
     contentsI = f.read() 
    with open('f2.txt') as f: 
     contentsO = f.read() 

    tokensI = Counter(value for value in contentsI.split() 
         if value not in []) 
    tokensO = Counter(value for value in contentsO.split() 
         if value not in []) 
    return not (tokensI - tokensO) and not (set(tokensO) - set(tokensI)) 

यह re.compile लागू करने के लिए संभव है:


प्रश्न भाग 2

मैं मैं Alfe से इस कोड को मिला 2 फ़ाइलें तुलना के बारे में एक अलग प्रश्न था और 'if value in []' सेक्शन में re.sub?

+0

हैलो:

आप सटीक परिणाम आप अपने प्रश्न में पता चला है प्राप्त करने के लिए पाठ की नई-पंक्तियों को निकालना चाहते हैं, कोड संशोधित किया जाना चाहिए। पहली समस्या में, टैग की तरह दिखने वाले सभी को हटाने का आपका इरादा है, या टैग वास्तव में मार्कअप भाषा के तत्व को परिभाषित करते हैं? मैं 'तत्व' शब्द का उपयोग अपने सही और सही अर्थ में करता हूं, जिसका अर्थ है 'टैग शुरू करें + तत्व सामग्री + अंत टैग'। - साथ ही, जैसा कि आपने फ़ाइल एफ की सामग्री का खुलासा किया है, इसमें लाइनें हैं, जो इसमें नई लाइनें कहती हैं। वांछित परिणाम के रूप में आप जो दिखाते हैं वह एक स्ट्रिंग है जिसमें कोई और नई लाइनें नहीं हैं। क्या यह वास्तव में आप चाहते हैं या आप संरचनाओं को लाइनों में रखना चाहते हैं? – eyquem

+0

'' यदि मूल्य में नहीं है []) '' के साथ आप क्या मतलब करना चाहते हैं? वर्तमान में इसका कोई मतलब नहीं है, क्योंकि शून्य सूची में हमेशा कुछ भी नहीं है। फाइलों की तुलना के रूप में आप क्या करना चाहते हैं? यह बहुत स्पष्ट नहीं है – eyquem

उत्तर

13

मैं समझाता है कि आपके कोड के साथ होता है:

import re 
file = open('f1.txt') 
fixed = open('fnew.txt','w') 
text = file.read() 

match = re.compile('<.*>') 
for unwanted in text: 
    fixed_doc = match.sub(r' ',text) 

fixed.write(fixed_doc) 

अनुदेश text = file.read() एक वस्तु पाठ के प्रकार स्ट्रिंगtext नामित पैदा करता है।
ध्यान दें कि मैं ऑब्जेक्ट को व्यक्त करने के लिए बोल्ड वर्ण टेक्स्ट का उपयोग करता हूं, और इस ऑब्जेक्ट का नाम == पहचानकर्ता व्यक्त करने के लिए text
निर्देश for unwanted in text: के परिणामस्वरूप, पहचानकर्ता unwanted को टेक्स्ट ऑब्जेक्ट द्वारा संदर्भित प्रत्येक वर्ण को लगातार सौंपा गया है।

इसके अलावा, re.compile('<.*>') प्रकार RegexObject की एक वस्तु (जो मैं personnaly संकलित कहते हैं) regex या बस regex, <.*> जा रहा है केवल regex पैटर्न) पैदा करता है।
आप इस संकलित रेगेक्स ऑब्जेक्ट को पहचानकर्ता match पर असाइन करते हैं: यह एक बहुत ही खराब अभ्यास है, क्योंकि match सामान्य रूप से रेगेक्स ऑब्जेक्ट्स की विधि का नाम है, और जिसे आपने विशेष रूप से बनाया है, तो आप बिना match.match लिख सकते हैं त्रुटि।
matchre मॉड्यूल के फ़ंक्शन का नाम भी है।
आपकी विशेष आवश्यकता के लिए इस नाम का उपयोग बहुत भ्रमित है। आपको इससे बचना चाहिए।

फ़ाइल f1 के फ़ाइल-हैंडलर के नाम के रूप में file के उपयोग के साथ एक ही त्रुटि है। file भाषा में पहले से ही एक पहचानकर्ता है, आपको इसे टालना चाहिए।

ठीक है। अब यह बुरा नाम मैच वस्तु परिभाषित किया गया है, अनुदेश fixed_doc = match.sub(r' ',text) सभी आवृत्तियां पाठ प्रतिस्थापन r' ' साथ में regex मैच द्वारा पाया बदल देता है।
ध्यान दें कि ' ' के बजाय r' ' लिखने के लिए यह पूरी तरह से अनिवार्य है क्योंकि ' ' में बिल्कुल कुछ भी नहीं है जिसे बचने की आवश्यकता है। यह कुछ चिंतित लोगों को एक रेगेक्स समस्या में स्ट्रिंग लिखने के लिए हर बार कच्चे तार लिखने का एक झगड़ा है।

इसका पैटर्न <.+> जिसमें डॉट प्रतीक का अर्थ है "लालच से एक < और अगर यह एक नई पंक्ति चरित्र है, सिवाय इसके एक > के बीच स्थित हर चरित्र खाने के लिए" की वजह से

, आवृत्तियां मैच द्वारा पाठ में catched तक प्रत्येक लाइन कर रहे हैं इसमें अंतिम > है।
नाम के रूप में unwanted इस निर्देश में प्रकट नहीं होता है, यह वही ऑपरेशन है जो पाठ के प्रत्येक चरित्र के लिए किया जाता है, एक दूसरे के बाद। यह कहना है: कुछ भी दिलचस्प नहीं है।
किसी प्रोग्राम के निष्पादन का विश्लेषण करने के लिए, आपको अपने कोड में कुछ प्रिंटिंग निर्देश देना चाहिए, जो समझने की अनुमति देता है कि क्या होता है।उदाहरण के लिए, यदि आप print repr(fixed_doc) करते हैं, तो आप इसे बार-बार प्रिंटिंग देखेंगे: ' \n \n \n '। जैसा कि मैंने कहा: कुछ भी दिलचस्प नहीं है। खुली फ़ाइलों आप, लेकिन आप उन्हें बंद नहीं है:

अपने कोड में एक और डिफ़ॉल्ट नहीं है। फ़ाइलों को बंद करना अनिवार्य है, अन्यथा यह कुछ अजीब घटनाएं हो सकती हैं, जिन्हें मैंने व्यक्तिगत रूप से इस आवश्यकता को महसूस करने से पहले मेरे कुछ कोडों में देखा है। कुछ लोग नाटक करते हैं कि यह अनिवार्य नहीं है, लेकिन यह झूठा है।
वैसे, खोलने के लिए और फ़ाइलों बंद करने के लिए बेहतर तरीके से with कथन का उपयोग करने के लिए है। यह आपके बिना काम करने के सभी काम करता है।

तो, अब मैं तुम्हें एक कोड आपकी पहली समस्या के लिए प्रस्ताव कर सकते हैं:

import re 

def ripl(mat=None,li = []): 
    if mat==None: 
     li[:] = [] 
     return 
    if mat.group(1): 
     li.append(mat.span(2)) 
     return '' 
    elif mat.span() in li: 
     return '' 
    else: 
     return mat.group() 

r = re.compile('</[^>]+>' 
       '|' 
       '<([^>]+)>(?=.*?(</\\1>))', 
       re.DOTALL) 

text = '''<something @37> 
<name>George <wxc>Washington</name> 
<a23c>Joe </zazaza>Taylor</a23c> 
</something @37>''' 
print '1------------------------------------1' 
print text 
print '2------------------------------------2' 
ripl() 
print r.sub(ripl,text) 
print '3------------------------------------3' 

परिणाम

1------------------------------------1 
<something @37> 
<name>George <wxc>Washington</name> 
<a23c>Joe </zazaza>Taylor</a23c> 
</something @37> 
2------------------------------------2 

George <wxc>Washington 
Joe </zazaza>Taylor 

3------------------------------------3 

सिद्धांत इस प्रकार है:

regex एक टैग पता लगाता है,
- अगर यह एक अंत टैग है, यह से मेल खाता है - अगर यह एक स्टार्ट टैग है, यह केवल से मेल खाता है, अगर वहाँ एक इसी समाप्ति टैग कहीं है आगे पाठ
प्रत्येक मैच के लिए, विधि regex r समारोह ripl() कॉल प्रतिस्थापन प्रदर्शन करने की sub() में।
यदि मैच एक स्टार्ट टैग के साथ है (जो रेगिक्स के निर्माण द्वारा टेक्स्ट में कहीं भी आवश्यक है, तो इसके बाद टैग ripl()'' देता है।
मैच समाप्त टैग के साथ है, तो ripl() रिटर्न '' ही अगर यह अंत टैग पाठ में पहले से है का पता लगाया गया एक पिछले स्टार्ट टैग की इसी समाप्ति टैग किया जा रहा है। यह एक सूची ली में रिकॉर्डिंग द्वारा प्रत्येक संभव अंत टैग की अवधि के दौरान प्रत्येक बार एक प्रारंभ टैग का पता लगाया जाता है और मेल खाने के दौरान संभव हो जाता है।

रिकॉर्डिंग सूची ली, आदेश है कि यह हमेशा एक ही सूची है कि समारोह ripl() (कृपया, डिफ़ॉल्ट तर्क के functionning undertsand करने का उल्लेख के प्रत्येक कॉल पर प्रयोग किया जाता है है में एक डिफ़ॉल्ट तर्क के रूप में परिभाषित किया गया है, क्योंकि यह सूक्ष्म है)।
li की परिभाषा के परिणामस्वरूप डिफ़ॉल्ट तर्क प्राप्त करने वाले पैरामीटर के रूप में, सूची ऑब्जेक्ट li कई पाठों का विश्लेषण करते समय रिकॉर्ड किए गए सभी स्पैन को बनाए रखा जाएगा यदि कई ग्रंथों का लगातार विश्लेषण किया जाएगा। पिछले पाठ मैचों के स्पैन को बनाए रखने के लिए सूची li से बचने के लिए, सूची को खाली करना आवश्यक है। एक regex के sub() विधि में इसके किसी भी उपयोग करने से पहले तर्क के बिना ripl() कॉल करने के लिए अनुमति देता है: मैं इतना है कि पहले पैरामीटर एक डिफ़ॉल्ट तर्क None साथ परिभाषित किया गया है समारोह लिखा था।
फिर, किसी को इसका उपयोग करने से पहले ripl() लिखना चाहिए।

import re 

def ripl(mat=None,li = []): 
    if mat==None: 
     li[:] = [] 
     return 
    if mat.group(1): 
     return '' 
    elif mat.group(2): 
     li.append(mat.span(3)) 
     return '' 
    elif mat.span() in li: 
     return '' 
    else: 
     return mat.group() 


r = re.compile('(*\n *)' 
       '|' 
       '</[^>]+>' 
       '|' 
       '<([^>]+)>(?=.*?(</\\2>)) *', 
       re.DOTALL) 

text = '''<something @37> 
<name>George <wxc>Washington</name> 
<a23c>Joe </zazaza>Taylor</a23c> 
</something @37>''' 
print '1------------------------------------1' 
print text 
print '2------------------------------------2' 
ripl() 
print r.sub(ripl,text) 
print '3------------------------------------3' 

परिणाम

1------------------------------------1 
<something @37> 
<name>George <wxc>Washington</name> 
<a23c>Joe </zazaza>Taylor</a23c> 
</something @37> 
2------------------------------------2 
George <wxc>WashingtonJoe </zazaza>Taylor 
3------------------------------------3 
+0

@Duboe में कोड लिखा है, कृपया मेरा उत्तर देखें। ध्यान दें कि इसमें उपयोग किए गए प्रतिस्थापन चरित्र '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' – eyquem

1

आप आसानी से ऐसा करने के लिए ब्यूटीफुल सूप का उपयोग कर सकते हैं:

from bs4 import BeautifulSoup 
file = open('f1.txt') 
fixed = open('fnew.txt','w') 

#now for some soup 

soup = BeautifulSoup(file) 

fixed.write(str(soup.get_text()).replace('\n',' ')) 

ऊपर पंक्ति का उत्पादन होगा:

George Washington Joe Taylor 

(यह कम से कम नमूना आप मुझे दिया साथ काम करता है)

क्षमा करें मैं भाग 2, शुभकामनाएं नहीं समझता!

+0

यह काफी अच्छा है हालांकि मैं उन एक्सटेंशन का उपयोग करने में सक्षम नहीं हूं जो पहले से शामिल नहीं हैं:/लेकिन thx मैं कुछ भविष्य की परियोजनाओं के लिए इसका उपयोग कर सकता हूं :) – dustinboettcher

0

पहला भाग यह पता चला कि यह गायब था? '

match = re.compile('<.*?>') 

चाल है।


फिर भी दूसरे प्रश्नों के बारे में निश्चित नहीं है। :/

+0

यह एक बहुत ही सरल समाधान है। उदाहरण के लिए '' text = 'अटलांटिक <--- यह एक सागर है। << >> \ n बाट <--- यह एक जानवर है * इसे '' re.sub ('<.+?>', '', '' 'का परिणाम हटाएं' '' '' 'अटलांटिक >> \ n बैट < --- यह एक जानवर है * इसे हटाएं * '''। ऐसे मामलों से बचने के लिए मैंने अपने उत्तर – eyquem

0

भाग 1 के लिए नीचे कोड स्निपेट आज़माएं। हालांकि के रूप में मो जनवरी

import re 
import os 
def main(): 
    f = open('sample_file.txt') 
    fixed = open('fnew.txt','w') 



    #pattern = re.compile(r'(?P<start_tag>\<.+?\>)(?P<content>.*?)(?P<end_tag>\</.+?\>)') 
    pattern = re.compile(r'(?P<start><.+?>)(?P<content>.*?)(</.+?>)') 
    output_text = [] 
    for text in f: 
     match = pattern.match(text) 
     if match is not None: 
      output_text.append(match.group('content')) 

    fixed_content = ' '.join(output_text) 


    fixed.write(fixed_content) 
    f.close() 
    fixed.close() 

if __name__ == '__main__': 
    main() 

ने सुझाव दिया भाग 2 लिए BeautifulSoup की तरह एक पुस्तकालय का उपयोग करें:

मैं तुम क्या कह रहे हैं के साथ पूरी तरह से स्पष्ट नहीं कर रहा हूँ - लेकिन मेरा अनुमान है कि आप क्या करना चाहते है if re.sub(value) not in [] जैसे कुछ। हालांकि, ध्यान दें कि Counter इंस्टेंस प्रारंभ करने से पहले आपको केवल re.compile पर कॉल करने की आवश्यकता है। यदि आप अपने प्रश्न के दूसरे भाग को स्पष्ट करते हैं तो यह बेहतर होगा।

दरअसल, मैं आपको दो फाइलों के बीच अंतर खोजने के लिए अंतर्निहित पायथन डिफ मॉड्यूल का उपयोग करने की सलाह दूंगा।अपने स्वयं के diff एल्गोरिदम का उपयोग करने से बेहतर तरीके से इसका उपयोग करना, क्योंकि diff तर्क अच्छी तरह से परीक्षण किया जाता है और व्यापक रूप से उपयोग किया जाता है और नकली न्यूलाइन, टैब और स्पेस वर्णों की उपस्थिति के परिणामस्वरूप तार्किक या प्रोग्रामेटिक त्रुटियों के लिए कमजोर नहीं है।

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