2012-12-01 13 views
6

मैं पाइपरिंग (और पाइथन के लिए बिल्कुल नया) में नया हूं। मैंने अपनी समस्या को सबसे सरल रूप में कम करने की कोशिश की है जो बताएगा कि क्या गलत हो रहा है (उस बिंदु पर जहां मुझे शायद पाइपर्सिंग की आवश्यकता नहीं होगी!)पाइपर्सिंग न्यूबी सेटपर्सएक्शन टॉकेन्स को संशोधित करना

मान लीजिए कि मेरे पास अक्षरों और संख्याएं शामिल हैं , जैसे "बी 7 जे 4 ए 2 डी सी 3"। हमेशा एक पत्र होता है, लेकिन संख्या वैकल्पिक है। मैं इसे अपने व्यक्तिगत तत्वों में पार्स करना चाहता हूं, और फिर उन्हें संसाधित करना चाहता हूं, लेकिन जहां कोई नंगे अक्षर है, बिना किसी संख्या के, इसे बदलने के लिए आसान होगा ताकि उसके बाद "डिफ़ॉल्ट" नंबर 1 हो। तब मैं हर तत्व को लगातार तरीके से संसाधित कर सकता था। मैंने सोचा कि मैं एक setparseAction के साथ ऐसा कर सकता है, इस प्रकार है:

from pyparsing import * 
teststring = "a2 b5 c9 d e z" 
expected_letter = Word("ABCDEFGabcdefgzZxy", exact=1) 
expected_number = Word(nums) 
letter_and_number = expected_letter + expected_number 
bare_letter = expected_letter 
bare_letter.setParseAction(lambda s,l,t: t.append("1")) 
elements = letter_and_number | bare_letter 
line = OneOrMore(elements) 
print line.parseString(teststring) 

दुर्भाग्य से, t.append() मैं क्या उम्मीद कर रहा हूँ, एक "1" की सूची में जोड़ने के लिए किया गया था जो ऐसा नहीं करता है पार्सड टोकन इसके बजाय, मुझे एक त्रुटि मिलती है: TypeError: 'str' ऑब्जेक्ट कॉल करने योग्य नहीं है।

शायद मैं वास्तव में वास्तव में मोटा होना चाहता हूं, लेकिन आप में से एक विशेषज्ञ कृपया मुझे सीधे सेट कर सकता है।

धन्यवाद

स्टीव

उत्तर

4

बुनियादी अवधारणाओं pyparsing के बारे में प्राप्त करने के लिए की है कि यह तार के सिर्फ सूचियों के साथ काम नहीं करता है, लेकिन एक ParseResults वस्तु में पार्स टुकड़े असेंबल। ParseResults एक समृद्ध डेटा प्रकार है जो पाइपर्सिंग में परिभाषित किया गया है, जिसे एक सूची के रूप में उपयोग किया जा सकता है, या एक टोक या ऑब्जेक्ट के रूप में यदि टोकन हैं जिन्हें एक परिभाषित परिणाम नाम के साथ पार्सरलेमेंट से पार्स किया गया है।

हालांकि, जबकि ParseResults को दिमाग में आसान पहुंच के साथ डिज़ाइन किया गया था, यह उन तरीकों से सीमित है जिन्हें इसे अपडेट किया जा सकता है। आंतरिक रूप से पाइपर्सिंग में, प्रत्येक अभिव्यक्ति जो मैचों से एक छोटी ParseResults ऑब्जेक्ट बनाता है; यदि यह एक बड़ी अभिव्यक्ति का हिस्सा है, तो अभिव्यक्ति + = ऑपरेटर का उपयोग करके टुकड़ों को एक बड़े ParseResults में जमा करती है।

आपके मामले में, आप ParseResults कि में "1" से युक्त और टी में जोड़ने से एक छोटा सा ParseResults बनाने के द्वारा पारित हो जाता है को संलग्न कर सकते हैं:

t += ParseResults("1") 

दुर्भाग्य से, यह एक लैम्ब्डा के रूप में काम नहीं करेगा - आप

lambda s,l,t: t.__iadd__(ParseResults("1")) 

पर कोशिश कर सकते हैं लेकिन यह थोड़ा बहुत चालाक लगता है।

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

>>> letter = Word(alphas,exact=1) 
>>> digit = Word(nums,exact=1) 
>>> teststring= "a2 b5 c9 d e z" 
>>> letter_and_digit = Combine(letter + Optional(digit, default="1")) 
>>> print (sum(letter_and_digit.searchString(teststring))) 
['a2', 'b5', 'c9', 'd1', 'e1', 'z1'] 

गठबंधन अन्यथा प्रत्येक मैच ['a','2'], ['b','5'] कैसा दिखेगा, तार में अलग अक्षरों और अंकों में पुन: शामिल करने के लिए प्रयोग किया जाता है, आदि

(आम तौर पर, searchString रिटर्न ParseResults ऑब्जेक्ट्स की एक सूची, जो सिंगल-एलिमेंट सूचियों की सूची की तरह दिखाई देगी। सर्चिंग के परिणामों को sum पर पास करके यह सब उन्हें स्ट्रिंग्स के केवल एक पैरासेजल्ट में जोड़ता है।)

+0

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

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