2010-04-14 8 views
10

में regex पर्ल में मैं) एक regexp में विभिन्न क्षेत्रों लेने, द्वारा (विभिन्न क्षेत्रों को अलग करने और उन्हें प्राप्त करने का उपयोग कर के लिए कुछ इस तरह करना होगा की तरह $पर्ल पायथन

foreach $line (@lines) 
{ 
$line =~ m/(.*?):([^-]*)-(.*)/; 
    $field_1 = $1 
    $field_2 = $2 
    $field_3 = $3 
} 

मैं कैसे में कुछ इस तरह कर सकता है अजगर?

उत्तर

8

पायथन re मॉड्यूल के साथ नियमित अभिव्यक्तियों का समर्थन करता है। re.search() विधि MatchObject देता है जिसमें group() जैसी विधियां हैं जिनका उपयोग आप "कैप्चरिंग समूह" जानकारी को पुनर्प्राप्त करने के लिए कर सकते हैं।

उदाहरण के लिए:

m = re.search(r'(.*?):([^-]*)-(.*)', line) 
field_1 = m.group(1) 
field_2 = m.group(2) 
field_3 = m.group(3) 
12

पर्ल में, आप संख्या के साथ scalars का एक समूह प्रत्यय लगाना से एक सरणी का उपयोग कर बंद ज्यादा बेहतर होगा। जैसे

foreach my $line (@lines) { 
    my @matches = ($line =~ m/(.*?):([^-]*)-(.*)/); 
    ... 
} 

अजगर में, re मॉड्यूल कब्जा-समूह जानकारी युक्त एक मैच वस्तु देता है। तो अगर आप लिख सकते हैं:

match = re.search('(.*?):([^-]*)-(.*)', line) 

फिर अपने मैचों match.group(1), match.group(2) में उपलब्ध होगा, आदि

6

और वह अजगर, TIMTOWTDI में भूल नहीं है;)

import re 
p = re.compile(r'(\d+)\.(\d+)') 
num_parts = p.findall('11.22 333.444') # List of tuples. 
print num_parts       # [('11', '22'), ('333', '444')] 
+0

मुझे लगता है कि आप पर्ल के साथ अजगर भ्रमित कर रहे हैं; बस 'आयात करें' पढ़ें (यानी, पायथन के जेन, या सिर्फ 'पायथन-सी "इसे आयात करें" | grep -i there') –

+0

@AleksiTorhamo शायद आप एक मजाक के साथ गंभीरता को भ्रमित कर रहे हैं? ;) – FMc

+0

आह, अच्छा :-) यह सिर्फ इतना है कि यह एक दिन में दूसरी बार था कि मैंने किसी को यह कहकर उछाल दिया, इसलिए मैंने सोचा कि मैं बेवकूफ/सूचनात्मक पक्ष पर बेहतर गलती करूंगा :) (और हाँ, मैं ' मुझे यकीन है कि * अन्य * लड़का गंभीर था: डी) –

18

"विहित "आपके स्निपेट का पायथन अनुवाद ...:

import re 

myre = re.compile(r'(.*?):([^-]*)-(.*)') 
for line in lines: 
    mo = myre.search(line) 
    field_1, field_2, field_3 = mo.groups() 

आयात करनाएक जरूरी है (आयात सामान्य रूप से मॉड्यूल के शीर्ष पर किया जाता है, लेकिन यह अनिवार्य नहीं है)। आरई प्रीकंपलिंग वैकल्पिक है (यदि आप re.search फ़ंक्शन का उपयोग करते हैं, तो यह आपके पैटर्न को मक्खी पर संकलित करेगा) लेकिन अनुशंसित (इसलिए आप अपने प्रदर्शन के लिए संकलित आरई ऑब्जेक्ट्स के मॉड्यूल कैश पर भरोसा नहीं करते हैं, और इसके लिए भी एक आरई ऑब्जेक्ट और इसकी विधियों को कॉल करें, जो पायथन में अधिक आम है)।

आप या तो match विधि का उपयोग कर सकते हैं (जो हमेशा प्रारंभ से मिलान करने का प्रयास करता है, चाहे आपका पैटर्न '^' से शुरू हो या नहीं) या search विधि (जो कहीं भी मिलान करने का प्रयास करता है); आपके दिए गए पैटर्न के साथ वे बराबर होना चाहिए (लेकिन मुझे 100% निश्चित नहीं है)।

.groups() विधि सभी मिलान करने वाले समूहों को वापस लाती है ताकि आप उन्हें सभी को एक गलप में असाइन कर सकें (पर्ल में एक सरणी का उपयोग करने की तरह, पाइथन में एक सूची का उपयोग करके, शायद अधिक सामान्य होगा, लेकिन चूंकि आपने पर्ल में स्केलर्स का उपयोग करना चुना है आप पाइथन में बराबर भी कर सकते हैं)।

यदि कोई पंक्ति आरई से मेल नहीं खाती है तो यह अपवाद के साथ असफल हो जाएगा, जो ठीक है अगर आपको पता है कि वे सभी मेल खाते हैं (मुझे यकीन नहीं है कि आपके पर्ल का व्यवहार क्या है लेकिन मुझे लगता है कि यह "पुन: उपयोग" करेगा इसके बजाय पिछले मिलान लाइन के मूल्य, जो अनोखा है ... जब तक, आप फिर से सभी पंक्तियों को नहीं जानते ;-)। तुम सिर्फ मेल नहीं खाने वाले लाइनों को छोड़ चाहते हैं, के लिए निम्न दो पिछले बयान बदलने के लिए:

if mo: 
     field_1, field_2, field_3 = mo.groups() 
5

बस एक विकल्प के उदाहरण के रूप में, अजगर बहुत अच्छा समर्थन named capture groups के लिए (नाम कैप्चर समूहों के लिए तथ्य यह है अजगर में बीड़ा उठाया सहायता प्रदान करता है)।

नामित कैप्चर समूह का उपयोग करने के लिए, आप केवल कैप्चर समूह के उद्घाटन कोष्ठक के अंदर ?P<the_name_of_the_group> जोड़ें।

यह आपको एक शब्दकोश में अपने मैचों के सभी प्राप्त करने के लिए बहुत आसानी से की अनुमति देता है:

>>> import re 
>>> x = re.search("name: (?P<name>\w+) age: (?P<age>\d+)", "name: Bob age: 20") 
>>> x.groupdict() 
{'age': '20', 'name': 'Bob'} 

यहाँ ओपी के उदाहरण, नामित कैप्चर समूहों

import re 

find_fields_regex = re.compile(r'(?P<field1>.*?):(?P<field2>[^-]*)-(?P<field3>.*)') 
for line in lines: 
    search_result = find_fields_regex.search(line) 
    all_the_fields = search_result.groupdict() 

अब all_the_fields उपयोग करने के लिए संशोधित है के साथ एक शब्दकोश है कैप्चर समूह नामों ("फ़ील्ड 1", "फ़ील्ड 2", और "फ़ील्ड 3") से संबंधित कुंजी और संबंधित कैप्चर समूहों की सामग्री से संबंधित मान।

तुम क्यों नामित पसंद करते हैं चाहिए कैप्चर समूहों

    नामित कैप्चर समूहों के साथ
  • , यह कोई बात नहीं यदि आप और अधिक कैप्चर समूहों जोड़ने या मौजूदा कैप्चर समूहों को दूर करने के लिए regex पैटर्न, संशोधित करने, सब कुछ अभी भी डाला जाता है सही कुंजी के नीचे शब्दकोश में। लेकिन नाम कैप्चर समूहों के बिना, आपको समूह की संख्या में हर बार अपने चर असाइनमेंट को दोबारा जांचना होगा।
  • नामित कैप्चर समूह आपके कैप्चर समूह स्वयं-दस्तावेज़ बनाते हैं।
  • तुम अब भी समूहों का उल्लेख करने के नंबरों का उपयोग कर सकते हैं अगर आप चाहते हैं:
>>> import re 
>>> x = re.search("name: (?P<name>\w+) age: (?P<age>\d+)", "name: Bob age: 20") 
>>> x.groupdict() 
{'age': '20', 'name': 'Bob'} 
>>> x.group(1) 
'Bob' 
>>> x.group(2) 
'20' 

कुछ अच्छी regex संसाधन: