2012-04-19 9 views
6

तो मेरे पास है:गणित समीकरण में नेस्टेड कोष्ठक को संभालने के लिए नियमित अभिव्यक्ति का उपयोग करें?

statement = "(2*(3+1))*2" 

मैं एक गणित पाठक मैं लिख रहा हूँ के लिए कोष्ठक के भीतर कई कोष्ठकों को संभालने में सक्षम होना चाहता हूँ। शायद मैं इस बारे में गलत तरीके से जा रहा हूं, लेकिन मेरा लक्ष्य तब तक ब्रांड्स में गहराई से जाना था जब तक कि कोई नहीं था, और फिर मैं गणित के संचालन करता। इस प्रकार, मैं पहली बार तब

"(3+1)" 

मैं regex के शुरू होने से सूचकांक और regex के अंत अनुक्रमण करने के लिए ध्यान देने के मूल्य बताए द्वारा ऐसा करने के लिए आशा व्यक्त की ध्यान केंद्रित

"(2*(3+1))" 

पर ध्यान केंद्रित करना चाहते हैं । मुझे अभी तक पता नहीं है कि अंत सूचकांक कैसे ढूंढें, लेकिन मुझे पहले रेगेक्स

r"\(.+\)" 

मिलान करने में विफल रहा है। मैं इसे "कोष्ठक के एक सेट के भीतर निहित किसी भी एक या अधिक वर्ण" के रूप में पढ़ना चाहता था। क्या कोई समझा सकता है कि उपर्युक्त अभिव्यक्ति पाइथन में उपर्युक्त कथन से मेल नहीं खाती है?

+0

पार्सर .......... –

+0

['आर" \ (। + \) "' मिलान करता है।] (Http://ideone.com/oJQjV) – Amber

उत्तर

12

मुझे नियमित अभिव्यक्ति पसंद है। मुझे उन्हें हर समय इस्तेमाल करना है।

इसके लिए नियमित अभिव्यक्तियों का उपयोग न करें।

आप एक वास्तविक पार्सर चाहते हैं जो वास्तव में आपके गणित अभिव्यक्तियों को पार्स करेगा। आप इस पढ़ने के लिए चाहते हो सकता है:

http://effbot.org/zone/simple-top-down-parsing.htm

एक बार जब आप वास्तव में अभिव्यक्ति पार्स है, यह तुच्छ है पार्स पेड़ चलना और परिणाम की गणना करने के।

संपादित करें: @ लैटवेयर ने पाइपर्सिंग का सुझाव दिया है, जो जाने का एक अच्छा तरीका भी होना चाहिए, और ऊपर पोस्ट किए गए ईएफएफबॉट समाधान से आसान हो सकता है।

http://pyparsing.wikispaces.com

यहाँ एक चार समारोह बीजीय अभिव्यक्ति मूल्यांकनकर्ता के लिए pyparsing नमूना कोड लिए एक सीधा लिंक है:

http://pyparsing.wikispaces.com/file/view/fourFn.py

+0

यह उल्लेखनीय भी हो सकता है ['pyparsing''] (http://pyparsing.wikispaces.com/) - हालांकि अगर यह सब कुछ चाहता है, तो यह अधिक होगा। –

+0

@Lattyware तो क्या आप पाइपरिंग का उपयोग करने की सलाह देंगे यदि मैं अपने पाइथन प्रोग्राम का उपयोग फाइल को पार्स करने और इसकी सामग्री की व्याख्या करने के लिए करना चाहता था जैसे कि यह किसी अन्य भाषा में कोड था? – purpleladydragons

+1

@purpleladydragons, पाइपर्सिंग आपको आवश्यक किसी भी पार्सर के निर्माण के लिए एक किट है। पाइपर्सिंग के लिए नमूना कोड में "चार-फ़ंक्शन बीजगणितीय नोटेशन पार्सर" शामिल है जो आपको एक प्रारंभिक बिंदु देगा: http://pyparsing.wikispaces.com/file/view/fourFn.py – steveha

1

मैं शायद steveha से सहमत हैं, और इस के लिए रेगुलर एक्सप्रेशन से सलाह नहीं देते , लेकिन विशेष रूप से आपके प्रश्न का उत्तर देने के लिए, आपको परिणाम समूहों को खींचने के लिए अनचाहे माता-पिता की आवश्यकता है (आपका पैटर्न केवल माता-पिता से बच निकला है):

>>> re.match(r"\((.+)\)", "(2*(3+1))*2").group(1) 
'2*(3+1)' 

यदि आप उस मार्ग पर जाते हैं, तो आप मिलान परिणामों से फिर से शुरू हो सकते हैं जब तक कि आप मैचों से बाहर नहीं हो जाते, और फिर परिणामों की सूची को अंदर से बाहर करने के लिए उलट दें।

2
क्या इसके लायक है के लिए

, यहाँ एक छोटे से अधिक संदर्भ है:

नियमित अभिव्यक्ति कहा जाता है "नियमित" क्योंकि वे नियमित व्याकरण के साथ जुड़े रहे हैं, और नियमित व्याकरण का वर्णन नहीं कर सकते हैं (एक असीमित संख्या) नेस्ट कोष्ठकों (वे यादृच्छिक कोष्ठक के गुच्छा का वर्णन कर सकते हैं, लेकिन उन्हें साफ जोड़े में मिलान नहीं कर सकते हैं)।

यह समझने का एक तरीका यह है कि नियमित अभिव्यक्तियां (कुछ विवरणों को संशोधित कर सकते हैं जिन्हें मैं अंत में समझाऊंगा) निर्धारिती परिमित automatons में परिवर्तित हो सकते हैं। जो भयभीत लगता है लेकिन वास्तव में इसका मतलब है कि उन्हें "नियम" की सूचियों में परिवर्तित किया जा सकता है, जहां नियम आपके द्वारा मिलान किए गए कार्यों पर निर्भर करते हैं, और वर्णन करते हैं कि आप क्या मिलान कर सकते हैं।

उदाहरण के लिए, नियमित अभिव्यक्ति ab*c में बदला जा सकता: शुरू में

  1. , आप केवल a मिलान कर सकते हैं। तो 2.

  2. के पास जाओ अब, आप b मिलान कर सकते हैं और 2 के लिए वापस जाओ, या मैच c और 3

  3. कार्य पूरा हो जाने के लिए जाना! मैच एक सफलता थी!

और यह एक "निर्धारक परिमित automaton" है।

वैसे भी, इसका दिलचस्प हिस्सा यह है कि यदि आप बैठते हैं और ब्रांड्स के जोड़ों के मिलान के लिए ऐसा कुछ करने की कोशिश करते हैं तो आप नहीं कर सकते! कोशिश करो। आप अधिक से अधिक नियम बनाकर एक सीमित संख्या से मेल खा सकते हैं, लेकिन आप नियमों का एक सामान्य सेट नहीं लिख सकते हैं जो असीमित संख्या में ब्रांड्स से मेल खाते हैं (मुझे यह जोड़ना चाहिए कि नियमों का होना चाहिए "यदि आप एक्स से मेल खाते हैं वाई के लिए ")।

अब स्पष्ट रूप से आप इसे विभिन्न तरीकों से संशोधित कर सकते हैं। आप अधिक जटिल नियमों की अनुमति दे सकते हैं (जैसे उन्हें आपको कोष्ठक की गिनती रखने के लिए विस्तारित करना), और फिर आप कुछ ऐसा प्राप्त कर सकते हैं जो आप उम्मीद करते हैं। लेकिन यह एक नियमित व्याकरण नहीं होगा।

यह देखते हुए कि नियमित अभिव्यक्ति इस तरह से सीमित हैं, वे कुछ और जटिल के बजाय क्यों उपयोग किए जाते हैं? यह पता चला है कि वे एक मीठे स्थान के कुछ हैं - वे काफी सरल और कुशल रहते हुए बहुत कुछ कर सकते हैं। अधिक जटिल व्याकरण (नियमों के प्रकार) अधिक शक्तिशाली हो सकते हैं, लेकिन कार्यान्वित करने के लिए भी कठिन हैं, और दक्षता के साथ और अधिक समस्याएं हैं।

अंतिम अस्वीकरण और अतिरिक्त विवरण का वादा किया: व्यावहारिक रूप से इन दिनों वास्तव में इस से अधिक शक्तिशाली हैं (और वास्तव में "नियमित अभिव्यक्ति" नहीं कहा जाना चाहिए)। लेकिन उपर्युक्त अभी भी मूलभूत स्पष्टीकरण है कि आपको इसके लिए regexp का उपयोग क्यों नहीं करना चाहिए।

ps जेसे का सुझाया गया समाधान कई बार regexp का उपयोग करके इसे गोल करता है; यहां तर्क regexp के एक ही उपयोग के लिए है।

+0

उपर्युक्त का संक्षिप्त सारांश: "नियमित अभिव्यक्तियां गिनती नहीं कर सकती हैं"।यह नियमित रूप से अभिव्यक्तियों को लागू करने के लिए बहुत सारे काम करेगा, ताकि उन्हें कोष्ठक के साथ अभिव्यक्तियों को संभाला जा सके। – steveha

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