2010-01-24 14 views
6

मैं नियमित अभिव्यक्तियों के साथ बहुत सभ्य हूं, और अब मैं एक बार फिर से देखने और समझने के लिए प्रयास करने की कोशिश कर रहा हूं। वे ज्यादातर समझ में आते हैं, लेकिन मुझे पूरा यकीन नहीं है कि आदेश परिणाम को कैसे प्रभावित करता है। मैं this site देख रहा हूं जो अभिव्यक्ति से पहले दिखता है, और अभिव्यक्ति के बाद दिखता है। मेरा सवाल है, क्या यह कुछ बदलता है? एसओ पर एक हालिया जवाब ने अभिव्यक्ति से पहले लुकहेड रखा जो मेरे भ्रम की ओर अग्रसर है।रेगेक्स लुकहेड ऑर्डरिंग

उत्तर

9

जब ट्यूटोरियल lookarounds पेश करते हैं, वे हर एक के लिए सबसे आसान उपयोग के मामले का चयन करने के लिए जाते हैं। इसलिए वे (?<!a)b ('बी' से पहले नहीं ')' 0 'या q(?=u) (' q 'के बाद' यू ') जैसे उदाहरणों का उपयोग करेंगे। यह केवल विचलित विवरणों के साथ स्पष्टीकरण को छेड़छाड़ करने से बचने के लिए है, लेकिन यह उस छाप को बनाने (या मजबूती) बनाता है जो दिखता है और देखो एक निश्चित क्रम में दिखने वाला होता है। उस विचार को पाने में मुझे थोड़ी देर लग गई, और मैंने कई अन्य लोगों को भी इससे पीड़ित देखा है।

कुछ और यथार्थवादी उदाहरणों को देखने का प्रयास करें। एक सवाल जो बहुत कुछ आता है पासवर्ड को मान्य करना शामिल है; उदाहरण के लिए, सुनिश्चित करें कि एक नया पासवर्ड कम से कम छह वर्ण लंबा है और इसमें कम से कम एक अक्षर और एक अंक शामिल है। एक तरीका यह है कि ऐसा करने के लिए होगा:

^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9]{6,}$ 

चरित्र वर्ग [A-Za-z0-9]{6,} सभी पत्र या सभी अंकों का मिलान कर सकते हैं, ताकि आप सुनिश्चित करने के लिए प्रत्येक के कम से कम एक बात यह है कि lookaheads का उपयोग करें। इस मामले में, आपको लुकहेड पहले करना है, क्योंकि रेगेक्स के बाद के हिस्सों को पूरी स्ट्रिंग की जांच करने में सक्षम होना चाहिए।

एक और उदाहरण के लिए, मान लें कि आपको "वहां" शब्द की सभी घटनाओं को खोजने की आवश्यकता है जब तक कि यह उद्धरण चिह्न से पहले न हो। इसके लिए स्पष्ट regex (?<!")[Tt]here\b है, लेकिन यदि आप एक बड़े कॉर्पस की खोज कर रहे हैं, तो यह एक प्रदर्शन समस्या पैदा कर सकता है। जैसा कि लिखा गया है, कि रेगेक्स पाठ में प्रत्येक स्थिति पर नकारात्मक दिखने वाला होगा, और केवल तभी जब यह सफल होगा, यह शेष रेगेक्स की जांच करेगा।

प्रत्येक रेगेक्स इंजन की अपनी ताकत और कमजोरियां होती हैं, लेकिन उनमें से एक बात यह है कि वे सभी के मुकाबले शाब्दिक पात्रों के निश्चित अनुक्रमों को ढूंढने के लिए जल्दी हैं - अनुक्रम जितना लंबा होगा उतना ही बेहतर होगा। इसका मतलब है कि यह lookbehind पिछले करना है, यह शब्द दो बार मिलान का मतलब है, भले ही नाटकीय रूप से तेजी से हो सकता है:

[Tt]here\b(?<!"[Tt]here) 

तो नियम lookarounds की नियुक्ति को नियंत्रित करने वाले कोई नियम है कि वहाँ है, आप उन्हें हर मामले में सबसे ज्यादा समझ में डाल देते हैं।

1

1(?=ABC) का अर्थ है - 1 देखें, और उसके बाद ABC मिलान करें (लेकिन कैप्चर न करें)।
(?<=ABC)1 का मतलब है - मौजूदा स्थान से पहले ABC मिलान करें (लेकिन कैप्चर न करें) और 1 से मेल खाना जारी रखें।
तो, सामान्य रूप से, आप अभिव्यक्ति के बाद लुकहेड रखेंगे और इससे पहले दिखेंगे।

जब हम अभिव्यक्ति के बाद एक नजर डालें, हम स्ट्रिंग को फिर से जांच रहे हैं जिसे हम पहले से ही से मेल खाते हैं। यह सामान्य बात है जब आपके पास जटिल परिस्थितियां होती हैं (आप इसे रेगेक्स के AND के रूप में सोच सकते हैं)। उदाहरण के लिए, Daniel Brückner द्वारा इस हाल के उत्तर पर एक नज़र डालें:

.&.(?<! &) 

सबसे पहले, आप दो पात्रों के बीच एक ampersand पर कब्जा। इसके बाद, आप जांचते हैं कि वे दोनों रिक्त स्थान नहीं थे (\S&\S यहां काम नहीं करेंगे, ओपी 1&_ पर कब्जा करना चाहता था)।

+0

'[^] और [^]' संभवतः '। &। (? Gumbo

+2

वह "यह और वह" से मेल नहीं खाएगा जबकि दिखने वाला संस्करण होगा। वैध समतुल्य होगा: '\ S & | & \ S' –

4

मुझे लगता है कि व्याख्या के मुकाबले एक उदाहरण में दिखाना आसान है, मुझे लगता है। चलो इस regex लेते हैं:

(?<=\d)(?=(.)\1)(?!p)\w(?<!q) 

क्या इसका मतलब यह है:

  1. (?<=\d) - सुनिश्चित करें कि क्या आता है पहले मैच की स्थिति एक अंक है बनाते हैं।
  2. (?=(.)\1) - सुनिश्चित करें कि हम जो भी चरित्र इस (समान) स्थिति से मेल खाते हैं, उसके बाद स्वयं की एक प्रति (बैकरेफर के माध्यम से) होती है।
  3. (?!p) - सुनिश्चित करें कि p कोई नहीं है।
  4. \w - एक पत्र, अंक या अंडरस्कोर से मेल खाते हैं। ध्यान दें कि यह पहली बार है जब हम वास्तव में चरित्र से मेल खाते हैं और उपभोग करते हैं।
  5. (?<!q) - सुनिश्चित करें कि अब तक हमने जो मिलान किया है वह q के साथ समाप्त नहीं होता है।

यह सब abc5ddx या 9xx नहीं बल्कि 5d या 6qq या asd6pp या add तरह तार से मेल खाएगी। ध्यान दें कि प्रत्येक दावा स्वतंत्र रूप से काम करता है। यह बस बंद हो जाता है, चारों ओर देखता है, और यदि सब ठीक है, तो मिलान जारी रखने की अनुमति देता है।

ध्यान दें कि अधिकांश (संभवतः सभी) कार्यान्वयन में, निश्चित रूप से निश्चित लंबाई होने की सीमा होती है। आप पुनरावृत्ति/वैकल्पिकता ऑपरेटरों जैसे ?, *, और + का उपयोग नहीं कर सकते हैं। ऐसा इसलिए है क्योंकि एक पैटर्न से मिलान करने के लिए हमें एक शुरुआती बिंदु की आवश्यकता होती है - अन्यथा हमें स्ट्रिंग में प्रत्येक बिंदु से प्रत्येक रूप से मिलान करने का प्रयास करना होगा।

  1. पाठ कर्सर की स्थिति:

    स्ट्रिंग a3b5ddx पर इस regex का एक नमूना रन इस प्रकार है 0.

    1. कोशिश की स्थिति में पहले lookbehind मैच के लिए -1 (के बाद से \d हमेशा से मेल खाता है 1 चरित्र)। हम नकारात्मक सूचकांक से मेल नहीं खा सकते हैं, इसलिए कर्सर को विफल और अग्रिम करें।
  2. पाठ कर्सर की स्थिति: 1.
    1. कोशिश स्थिति 0. a में पहली lookbehind से मेल नहीं खाता \d इसलिए असफल और फिर कर्सर अग्रिम मैच के लिए।
  3. पाठ कर्सर की स्थिति: 2.
    1. कोशिश स्थिति 1. 3 में पहली lookbehind मैच के लिए मैच \d तो कर्सर बरकरार रखने के लिए और मिलान के लिए जारी है।
    2. स्थिति 2 पर पहले लुकहेड से मिलान करने का प्रयास करें। b मैचों (.) और कब्जा कर लिया गया है। 5\1 से मेल नहीं खाता (जो कब्जा b है)। इसलिए, कर्सर को विफल और अग्रिम करें।
  4. पाठ कर्सर की स्थिति: 3.
    1. कोशिश स्थिति 2. b में पहली lookbehind से मेल नहीं खाता \d इसलिए असफल और फिर कर्सर अग्रिम मैच के लिए।
  5. पाठ कर्सर की स्थिति: 4.
    1. कोशिश स्थिति 3. 5 में पहली lookbehind मैच के लिए मैच \d तो कर्सर बरकरार रखने के लिए और मिलान के लिए जारी है।
    2. स्थिति 4 पर पहले लुकहेड से मिलान करने का प्रयास करें। d मैचों (.) और कब्जा कर लिया गया है। दूसरा d\1 से मेल खाता है (जो पहले कब्जा d है)। मिलान को छोड़ने दें जहां से हमने छोड़ा था।
    3. दूसरे लुकहेड से मिलान करने का प्रयास करें। b स्थिति 4 पर p से मेल नहीं खाता है, और चूंकि यह एक नकारात्मक रूप है, यही वह है जिसे हम चाहते हैं; मिलान जारी रखने की अनुमति दें।
    4. स्थिति \w से स्थितिमैचों पर मिलान करने का प्रयास करें। एडवांस कर्सर क्योंकि हमने एक चरित्र खा लिया है और जारी रखा है। इसे मैच की शुरुआत के रूप में भी चिह्नित करें।
  6. पाठ कर्सर की स्थिति: (के बाद से q हमेशा 1 चरित्र से मेल खाता है) 5.
    1. कोशिश 4 स्थान पर दूसरा lookbehind मैच के लिए। dq से मेल नहीं खाता है जो हम नकारात्मक दिखने से चाहते हैं।
    2. यह समझें कि हम रेगेक्स के अंत में हैं और मैच की शुरुआत से वर्तमान स्थिति (4 से 5) तक सबस्ट्रिंग लौटकर सफलता की रिपोर्ट करते हैं, जो d है।
संबंधित मुद्दे