2008-10-23 4 views
20

कृपया स्पष्ट का उत्तर न दें, लेकिन सीमा संकेत क्या हैं जो हमें बताते हैं कि नियमित अभिव्यक्तियों का उपयोग करके हल नहीं किया जाना चाहिए?एक नियमित अभिव्यक्ति के लिए एक मुद्दा बहुत जटिल कब है?

उदाहरण के लिए: नियमित अभिव्यक्ति के लिए एक पूर्ण ईमेल सत्यापन बहुत जटिल क्यों है?

उत्तर

9

जब आपको किसी अभिव्यक्ति को पार्स करने की आवश्यकता होती है जिसे regular language द्वारा परिभाषित नहीं किया गया है।

+1

ठीक है, पर्ल एक्सटेंशन हैं। वे नियमित भाषाओं की कक्षा से बाहर निकलते हैं। – ADEpt

+0

मैं एक और व्यावहारिक दृष्टिकोण देखना चाहता हूं, लेकिन अब तक यह सही जवाब है। – Null303

+0

लिंक के बाद ... "इसे औपचारिक नियमित अभिव्यक्ति द्वारा वर्णित किया जा सकता है।" आपकी परिभाषा परिपत्र है। : पी – BoltBait

-1

मेरे सीमा एक Regex पैटर्न 30-50 के बारे में वर्ण लंबा है कि है (बदलती कितना निश्चित पाठ और कितना है regex आदेशों है के आधार पर)

0

एक समस्या नियमित अभिव्यक्ति के लिए बहुत जटिल है जब समस्या की कमी समाधान लिखने के बाद बदल सकते हैं। तो, आपके उदाहरण में, आप कैसे सुनिश्चित कर सकते हैं कि ईमेल पता मान्य है जब आपके पास लक्षित मेल सिस्टम तक पहुंच नहीं है यह सत्यापित करने के लिए कि ईमेल पता वैध उपयोगकर्ता से जुड़ा हुआ है? आप नहीं कर सकते

+0

आरएफसी 2822 मानक का पालन करने वाला ईमेल गीला या मान्य नहीं है यह निर्धारित करने की एक ही समस्या नहीं है कि वह ईमेल पता वास्तव में उपयोग में है या नहीं। – mmcdole

+0

सच है। लेकिन मूल सवाल यह था कि "एक नियमित अभिव्यक्ति के लिए एक समस्या बहुत जटिल कब है?" और मैंने एक समस्या का एक उदाहरण दिया जो नियमित अभिव्यक्तियों के लिए बहुत जटिल है। तो, जो भी मुझे नीचे वोट दिया, "तुम एक लामर हो!" : पी – BoltBait

3

किसी रेगेक्स के साथ समस्या हल करें, फिर इसे किसी और को regexes में बातचीत दें। यदि वे आपको बता नहीं सकते कि यह लगभग 10 मिनट में क्या करता है (या कम से कम आत्मविश्वास के साथ कहता है), यह बहुत जटिल है।

4

यहाँ रेमंड चेन से एक अच्छा उद्धरण है:

नियमित अभिव्यक्ति है कि वे क्या में अच्छा नहीं कर रहे हैं करना मत करना। यदि आप एक साधारण पैटर्न से मेल खाना चाहते हैं, तो एक साधारण पैटर्न से मेल खाते हैं। यदि आप गणित करना चाहते हैं, तो गणित करें। जैसा कि टिप्पणीकार Maurits कहते हैं, "चाल समय बिताना है नहीं करने के लिए एक संयोजन हथौड़ा/पेचकश विकासशील, लेकिन सिर्फ एक हथौड़ा और एक पेचकश का उपयोग

Source

3

निश्चित संकेत regexps उपयोग करते हुए इस बंद करने के लिए।: यदि आपके पास कई समूह ब्रेसिज़ '()' और कई विकल्प हैं '| तो यह एक निश्चित संकेत है कि आप नियमित अभिव्यक्ति के साथ एक (जटिल) पार्स करने करने की कोशिश है।

मिश्रण में जोड़े पर्ल एक्सटेंशन, backreferences, आदि और जल्द ही आप अपने आप को एक पार्सर कि पढ़ने के लिए कठिन है, मुश्किल संशोधित करने के लिए, और इसके गुणों के बारे में तर्क करने में कठिनाई (उदाहरण के लिए एक इनपुट है जिस पर यह पार्सर घातीय समय में काम करेगा)

यह रेगेक्सिंग रोकने और पार्सिंग शुरू करने का एक समय है (हाथ से बने पार्सर, पार्सर के साथ जनरेटर या पार्सर संयोजक)

2

जबरदस्त अभिव्यक्तियों के साथ, शब्दों पर प्रमुख सीमाएं हैं, जिन्हें regexp द्वारा नियंत्रित किया जा सकता है। उदाहरण के लिए आप n chars a द्वारा वर्णित शब्द के लिए regexp नहीं लिख सकते हैं, फिर n chars b, जहां n कोई भी हो सकता है, अधिक सख्ती से alt text

विभिन्न भाषाओं में regexp Regular language का विस्तार है, लेकिन पार्सिंग का समय बेहद बड़ा हो सकता है और यह कोड गैर-पोर्टेबल है।

+0

मुझे विषय के पीछे गणित में बहुत दिलचस्पी है। कृपया, क्या आप कह सकते हैं कि आपको अपनी अभिव्यक्ति कहां मिली है। गणित के बिना चीजों को समझना मेरे लिए मुश्किल है। –

+0

मैं यहां सीमाओं के वास्तविक अर्थ को समझ नहीं पा रहा हूं। आप इस तरह की शर्तों को नहीं बना सकते: 'if (n = k) प्रिंट करें "ए" सात बार;' आप regex में एक if-वाक्य नहीं लिख सकते हैं? –

+0

यदि सही समझा गया है, तो आप रेगेक्स में एक निहितार्थ नहीं कर सकते (या कहें कि यह इसका मुख्य उद्देश्य नहीं है)। इसलिए, आप ब्रांड्स से मेल खाने वाली चीजों को नहीं कर सकते हैं या "एन वर्णों द्वारा वर्णित किसी शब्द के लिए regexp लिखें"। रेगेक्स केवल मिलान के बारे में है। –

14

नियमित अभिव्यक्ति finite-state automata का एक पाठपरक प्रतिनिधित्व है। यही कहना है, वे केवल गैर-पुनरावर्ती मिलान तक ही सीमित हैं। इसका मतलब है कि आपके regexp में "स्कोप" या "उप-मिलान" की कोई अवधारणा नहीं हो सकती है। निम्न समस्या पर विचार करें:

(())() 

क्या सभी खुले माता-पिता एक करीबी माता-पिता से मेल खाते हैं?

जाहिर है, जब हम इसे मनुष्यों के रूप में देखते हैं, तो हम आसानी से देख सकते हैं कि उत्तर "हां" है। हालांकि, कोई नियमित अभिव्यक्ति विश्वसनीय रूप से इस प्रश्न का उत्तर देने में सक्षम नहीं होगी। इस प्रकार की प्रसंस्करण करने के लिए, आपको एक पूर्ण pushdown automaton (एक स्टैक के साथ एक डीएफए) की आवश्यकता होगी। यह आमतौर पर एएनटीएलआर या बाइसन द्वारा उत्पन्न पार्सर की नींव में पाया जाता है।

+0

.NET regex स्वाद को ब्रांड्स मिलान समस्या को हल करने में सक्षम होने के लिए बढ़ाया गया है (http://msdn.microsoft.com/en-us/library/bs2twtah.aspx)। ऐसा लगता है कि उन्होंने माइक्रोसॉफ्ट में धोखा दिया।:) –

1

जब भी आप यकीन है कि यह वास्तव में उदाहरण के लिए, समस्या का हल नहीं किया जा सकता:

  • एचटीएमएल पार्स
  • ईमेल सत्यापन
  • भाषा पारसर्स

खास तौर पर इसलिए जब वहाँ पहले से मौजूद हैं उपकरण जो पूरी तरह से समझने योग्य तरीके से समस्या को हल करते हैं।

रेगेक्स का उपयोग मेरे द्वारा उल्लिखित डोमेन में किया जा सकता है, लेकिन केवल पूरी समस्या का सबसेट और विशिष्ट, सरल मामलों के लिए।

यह रेगेक्स (नियमित भाषा + एक्सटेंशन) की तकनीकी सीमाओं से परे है, रखरखाव और पठनीयता सीमा अधिकांश मामलों में तकनीकी सीमा से काफी पहले है।

-1

यह बेवकूफ लग सकता है लेकिन मैं अक्सर नियमित अभिव्यक्ति का उपयोग कर डेटाबेस प्रकार के प्रश्नों को करने में सक्षम नहीं होने का शोक करता हूं। अब विशेष रूप से इससे पहले कि मैं खोज इंजन पर हर समय खोज स्ट्रिंग में प्रवेश कर रहा हूं। +complex AND +"regular expression"

खोजना असंभव नहीं है, उदाहरण के लिए, मैं उनके नाम पर बफर और विंडो दोनों के आदेशों के लिए emacs में कैसे खोजूं? मुझे अलग-अलग .*Buffer.*Window and .*Window.*Buffer

7

सामान्य ज्ञान का उपयोग करने के लिए नीचे क्या आता है। यदि आप जो मिलान करने की कोशिश कर रहे हैं वह एक अप्रबंधनीय, राक्षस नियमित अभिव्यक्ति बन जाता है तो आपको या तो इसे छोटे, तार्किक उप-नियमित अभिव्यक्तियों में तोड़ने की आवश्यकता होती है या आपको अपने समाधान को फिर से सोचने की आवश्यकता होती है।

ईमेल पते लें (आपके उदाहरण के अनुसार)। यह सरल नियमित अभिव्यक्ति (रेगुलर एक्सप्रेशन से साथी से लिया गया) वहाँ बाहर सभी ईमेल के 99% से मेल खाता है:

\b[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}\b 

यह संक्षिप्त और सटीक है और आप शायद ही कभी इसके साथ मुद्दों में चलेंगे। हालांकि, जैसा कि RegEx दोस्त के लेखक बताते हैं, यदि आपका ईमेल पता दुर्लभ शीर्ष-स्तरीय डोमेन "संग्रहालय" में है, तो इसे स्वीकार नहीं किया जाएगा।

RFC 2822 नामक मानक के पालन के लिए आपको आवश्यक सभी ईमेल पतों से मिलान करने की आवश्यकता है। यह ईमेल पते को स्वरूपित किए जा सकने वाले तरीकों की रूपरेखा बताता है और यह बेहद जटिल है।

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|" 
(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x 
0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9] 
(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.) 
{3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08 
\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]) 

यह स्पष्ट रूप से रिटर्न ह्रासमान के एक समस्या बन जाता है:

यहां नमूने नियमित अभिव्यक्ति RFC 2822 का पालन करने का प्रयास कर रहा है। आसानी से बनाए रखा कार्यान्वयन का उपयोग करना बेहतर है जो 99% ईमेल पते से मेल खाता है जो राक्षसों का बना है जो उनमें से 99.9% स्वीकार करता है।

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

+0

क्या आप वाकई पहले उदाहरण पर इसका मतलब नहीं रखते हैं? \ b [ए-जेड 0-9 ._% + -] + @ [ए-जेड 0-9 -] + \। [एजेड] {2,4} \ बी – Keng

+0

क्या आपने अभी जो पोस्ट किया है उसके बीच अंतर को हाइलाइट कर सकते हैं और जो मेरे पास है? मैं इसे नहीं देखता हूँ। – mmcdole

+0

अंतर ब्रैकेट के दूसरे सेट में डॉट है (सिमुकल का शाब्दिक बिंदु से पहले किसी भी चरित्र [तर्क के आधार पर नई लाइन के अलावा] मिलान होगा), और उनमें से कोई भी वास्तव में महान नहीं है (उदाहरण के लिए वे सबडोमेन की अनुमति नहीं देते हैं) । – eyelidlessness

13

कुछ बातों के लिए बाहर देखने के लिए:

  1. शुरुआत और टैग का पता लगाने को समाप्त हुए - मिलान किया जोड़ी
  2. प्रत्यावर्तन
  3. पीछे की ओर जाने के लिए (हालांकि आप स्ट्रिंग रिवर्स कर सकते हैं की आवश्यकता होगी,, लेकिन यह एक हैक है)

regexes, जितना मैं उन्हें प्यार करता हूं, उन तीन चीजों में अच्छा नहीं है। और याद रखें, इसे आसान रखें! यदि आप एक रेगेक्स बनाने की कोशिश कर रहे हैं जो "सब कुछ" करता है, तो you're probably doing it wrong

6

नियमित अभिव्यक्ति टेक्स्ट के व्यक्तिगत बिट्स टोकनिंग, ढूंढने या पहचानने के लिए उपयुक्त हैं, उदा। स्रोत कोड में कीवर्ड, तार, टिप्पणियां इत्यादि ढूंढना।

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

अनिवार्य रूप से, यदि आप "संतुलन समूह" (.NET के कैप्चर समूह घटाव सुविधा) या "रिकर्सन" (पर्ल 5.10 और पीसीआरई) के बारे में सोचना शुरू करते हैं तो आप अपने नियमित अभिव्यक्तियों के साथ दूर जा रहे हैं।

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