2010-09-26 8 views
31

उदाहरण के लिए, नीचे regex विफलता रिपोर्टिंग देखेंगेबिंद धारणा निश्चित लंबाई तय नहीं है:Regex में "दृढ़ विश्वास दृढ़ता तय होना चाहिए" के लिए तकनीकी कारण क्या है?

#(?<!(?:(?:src)|(?:href))=["\']?)((?:https?|ftp)://[^\s\'"<>()]+)#S 

इस प्रकार का प्रतिबंध lookahead के लिए मौजूद नहीं है।

+0

क्या संदर्भ आप "lookbehind अभिकथन लंबाई तय की जानी चाहिए" के लिए उपयोग कर रहे हैं? – Alex

+0

** दावा के अनुसार दृढ़ता तय नहीं है ** विफलता का कारण बन जाएगा, क्या हम इसे इससे अनुमान नहीं लगा सकते हैं? – wamp

+0

आप किस रेगेक्स इंजन का उपयोग कर रहे हैं? पर्ल? सी#? पीएचपी? वहाँ कई सारे उपकरण हैं जो रेगेक्स को संभालते हैं, और सभी के पास अपने स्वयं के क्विर्क हैं – Yuliy

उत्तर

53

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

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

यह एक सकल oversimplification है, निश्चित रूप से, और सभी स्वाद इस तरह से काम नहीं करते हैं, लेकिन आप विचार मिलता है। जिस तरह से दिखने के लिए आवेदन किया जाता है वह मौलिक रूप से अलग होता है (और अधिक, अधिक उससे कम कुशल) जिस तरह से लुकहेड लागू होते हैं। यह केवल एक सीमा तय करने के लिए समझ में आता है कि देखो को देखने के लिए कितनी दूर है।

+4

+1। :-) –

+0

तो आप पहले देखने के पीछे क्यों नहीं देख सकते हैं, और फिर बाकी पैटर्न ढूंढ सकते हैं? –

+2

@ एडनमुएलर: कुछ स्वाद (पीसीआरई सहित) '\ K' निर्माण का समर्थन करते हैं, जो केवल यही करता है:' foo \ kbar' को पहले 'foo' से मेल खाना पड़ेगा, लेकिन मैच को वास्तव में' बार 'पर शुरू किया गया है। लेकिन यह केवल * सकारात्मक * lookbehinds के लिए काम करता है। –

8

सबसे पहले, यह सभी नियमित अभिव्यक्ति पुस्तकालयों (जैसे .NET) के लिए सच नहीं है।

PCRE के लिए, कारण प्रतीत होता है:

lookbehind के कार्यान्वयन दावे कर रहा है, प्रत्येक विकल्प के लिए, अस्थायी रूप से वर्तमान स्थिति वापस निश्चित चौड़ाई से स्थानांतरित करने के लिए और तो जैसा बनाने का प्रयास ।

(कम से कम, http://www.autoitscript.com/autoit3/pcrepattern.html के अनुसार)।

+1

'लुकहेड' और 'lookbehind' के लिए एक ही एल्गोरिदम का उपयोग क्यों नहीं करें? प्रोटोटाइप वही नहीं है? – wamp

+2

वैंप, तो आपको पीछे की तरफ और पीछे की ओर रेगेक्स * रिवर्स करना होगा। नियमित अभिव्यक्ति आमतौर पर केवल आगे काम करती है और एक विशेष अभिव्यक्ति को उलट करने की संभावना है। – Joey

+0

वे एक फिक्स साइज चेकर को कार्यान्वित करने में सक्षम थे ('# (? <= Fw (* SKIP) (* FAIL) | f) ओओ #') का प्रयास करें, जबकि दाएं से बाएं क्षमता में कमी की कमी है। उत्कृष्ट स्पष्टीकरण एलन, धन्यवाद के लिए –

2

मैं एक ही मुद्दा था और (?: subexpression)

एक noncapturing समूह को परिभाषित करता है का उपयोग करके इसे तय की। इस तरह के Write(?:Line)? में "WriteLine" "Console.WriteLine()" "लिखें" में "Console.Write (मान)" के रूप में

मैं Regex बदलना पड़ा जो नीचे से पहले ,या पकड़ने के लिए लगता है स्ट्रिंग की शुरुआत में कुछ जो मुझे दे रहा था, दृढ़ता से अनुमान निर्धारित लंबाई नहीं है।

(?<=,|^) 
इस के साथ

,

(?:(?<=,)|^) 
2

PCRE चल lookbehind का समर्थन नहीं करता है क्योंकि यह प्रमुख प्रदर्शन समस्याएं पैदा कर सकता। यह दाएं से बाएं मिलान की क्षमता की कमी के कारण है: पीसीआरई केवल एक निश्चित बाएं से शाखा शुरू कर सकता है, लेकिन एक चर-लंबाई के बाईं तरफ से छोड़ा जा सकता है।

आम तौर पर, यदि संभव हो तो निश्चित लंबाई पैटर्न पर अपने दिखने वाले हिस्से को ब्रांच करने का प्रयास करें। के बजाय उदाहरण के लिए:

(?<=(src|href)=")etc. 

(1) उपयोग करें:

(?:(?<=src=")|(?<=href="))etc. 

(2) या \K साथ:

(src|href)="\Ketc. 

ध्यान दें कि \K एक असली नहीं है देखो, क्योंकि यह हमेशा पिछले मैच के अंत में खोज शुरू करता है (पिछले मैक में कोई संभावित बैकस्टेप नहीं ज)।

(3) कुछ जटिल दिखने वाले मामलों में आप एक उलटा स्ट्रिंग में "उलटा" लुकहेड अभिव्यक्ति के साथ खोज सकते हैं। नहीं भी सुरुचिपूर्ण, लेकिन यह काम करता है:

.cte(?="=(ferh|crs)) 
0
grep -P '(?<=((three)|(one)))two' <<< "one two three three two one" 
grep: lookbehind assertion is not fixed length 

grep -P '((?<=(three))|(?<=(one)))two' <<< "one two three three two one" 
one two three three two one 
+2

आपके उत्तर के लिए धन्यवाद! क्या आप केवल आदेशों के बजाय कुछ संदर्भ या अतिरिक्त जानकारी प्रदान कर सकते हैं? इससे जानकारी तलाशने वाले अन्य लोगों के लिए उत्तर अधिक उपयोगी होगा। – roelofs

+1

यह प्रश्न का उत्तर नहीं प्रदान करता है। एक बार आपके पास पर्याप्त [प्रतिष्ठा] (https://stackoverflow.com/help/whats-reputation) हो जाने पर आप [किसी भी पोस्ट पर टिप्पणी कर सकेंगे] (https://stackoverflow.com/help/privileges/comment); इसके बजाय, [उन उत्तरों को प्रदान करें जिन्हें पूछताछ से स्पष्टीकरण की आवश्यकता नहीं है] (https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can- i-कर-बजाय)। - [समीक्षा से] (/ समीक्षा/कम गुणवत्ता वाले पदों/18213583) – robinCTS

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