इस एक का प्रयास करें:
'~(?P<opening>\{(?P<inverse>[!])?block:(?P<name>[a-z0-9\s_-]+)\})(?P<contents>[^{]*(?:\{(?!/block:(?P=name)\})[^{]*)*)(?P<closing>\{/block:(?P=name)\})~i'
या, पठनीय रूप में:
'~(?P<opening>
\{
(?P<inverse>[!])?
block:
(?P<name>[a-z0-9\s_-]+)
\}
)
(?P<contents>
[^{]*(?:\{(?!/block:(?P=name)\})[^{]*)*
)
(?P<closing>
\{
/block:(?P=name)
\}
)~ix'
सबसे महत्वपूर्ण हिस्सा (?P<contents>..)
समूह में है:
[^{]*(?:\{(?!/block:(?P=name)\})[^{]*)*
बाहर शुरू, एकमात्र चरित्र जिसे हम रुचि रखते हैं वह उद्घाटन ब्रेस है, इसलिए हमके साथ किसी अन्य पात्र को स्लिप कर सकते हैं। केवल {
देखने के बाद हम यह देखने के लिए जांचते हैं कि यह {/block}
टैग की शुरुआत है या नहीं। यदि ऐसा नहीं है, तो हम आगे बढ़ते हैं और इसे उपभोग करते हैं और अगले के लिए स्कैनिंग शुरू करते हैं, और आवश्यकतानुसार दोहराते हैं।
रेगेक्सबड्डी का उपयोग करके, मैंने कर्सर को {block:sponsors}
टैग और डिबगिंग की शुरुआत में प्रत्येक रेगेक्स का परीक्षण करके परीक्षण किया। तब मैंने एक असफल मैच को मजबूर करने के लिए समापन {/block:sponsors}
टैग से समापन ब्रेस हटा दिया और इसे फिर से डीबग किया। आपके रेगेक्स ने सफल होने के लिए 940 कदम उठाए और असफल होने के लिए 2265 कदम उठाए। मेरा सफल होने के लिए 57 कदम और असफल होने के लिए 83 कदम उठाए।
एक तरफ नोट पर, मैंने s
संशोधक को हटा दिया क्योंकि क्योंकि मैं डॉट (.
), और m
संशोधक का उपयोग नहीं कर रहा हूं क्योंकि इसकी आवश्यकता नहीं थी। मैंने @ डेवआरैंडम के उत्कृष्ट सुझाव के अनुसार \3
के बजाय नामित बैकरेफर (?P=name)
का भी उपयोग किया। और मैं सभी ब्रेसिज़ ({
और }
) से बच निकला क्योंकि मुझे इस तरह से पढ़ने में आसान लगता है।
संपादित करें: आप अंतरतम नामित ब्लॉक मैच के लिए चाहते हैं, इस से regex के मध्य भाग को बदलें: (
(?P<contents>
[^{]*(?:\{(?!/block:(?P=name)\})[^{]*)*
)
... इस के रूप में द्वारा सुझाए @ उसकी टिप्पणी में कोबी):
(?P<contents>
[^{]*(?:\{(?!/?block:[a-z0-9\s_-]+\})[^{]*)*
)
मूल रूप से, (?P<opening>...)
समूह पहले खुलने वाला टैग हड़पने हैं यह देखा, तो (?P<contents>..)
समूह अन्य टैग सहित - कुछ टैग्स का उपभोग करेगा - जब तक वे (?P<opening>...)
समूह द्वारा प्राप्त किसी से मेल खाने के लिए समापन टैग नहीं थे। (फिर (?P<closing>...)
समूह आगे बढ़ने और उपभोग कि।)
अब, (?P<contents>...)
समूह (ध्यान दें शुरुआत में /?
) किसी भी टैग, खोलने या बंद करने से मिलान करने, कोई बात नहीं क्या नाम है मना कर दिया। तो रेगेक्स शुरू में {block:sponsors}
टैग से मेल खाना शुरू कर देता है, लेकिन जब यह {block:test}
टैग से मुकाबला करता है, तो वह उस मैच को छोड़ देता है और एक ओपनिंग टैग खोजने के लिए वापस जाता है। यह {block:test}
टैग पर फिर से शुरू होता है, इस बार जब यह {/block:test}
समापन टैग पाता है तो सफलतापूर्वक मैच को पूरा कर लेता है।
यह इस तरह का वर्णन करने में अक्षम लगता है, लेकिन यह वास्तव में नहीं है। जिस चाल को मैंने पहले वर्णित किया था, गैर-ब्रेसिज़ को फिसलकर, इन झूठी शुरुआतओं के प्रभाव से डूब गया। जहां आप लगभग हर स्थिति में नकारात्मक दिख रहे थे, अब आप केवल एक ही कर रहे हैं जब आप {
का सामना करते हैं।तुम भी, अधिकार परिमाणकों इस्तेमाल कर सकते हैं के रूप में के रूप में @godspeedlee सुझाव:
(?P<contents>
[^{]*+(?:\{(?!/?block:[a-z0-9\s_-]+\})[^{]*+)*+
)
... क्योंकि आप जानते हैं कि यह कुछ भी है कि यह बाद में वापस देना होगा उपभोग कभी नहीं होगा। इससे चीजें थोड़ा तेज हो जाएंगी, लेकिन यह वास्तव में जरूरी नहीं है।
अजीब के रूप में यह लग रहा है, मैं एक बार एक regex कि रखा था एक विशेष अपाचे उदाहरण और 'एस' (* ऊपरी मामला! *) ध्वज खाने से इसे ठीक किया गया। मैंने अनुमान लगाया कि यह एक अपरिवर्तित स्मृति रिसाव था या कुछ और अध्ययन प्रक्रिया से बचा जा सकता था। लंबे शॉट लेकिन कोशिश करने लायक है, मैं कहूंगा ... – DaveRandom
@ डेव रैंडम, एक ही फिक्स के साथ, मुझे एक ही समस्या थी! चलिए देखते हैं कि यह ओपी –
के लिए करता है एक और विचार यह होता है कि रेगेक्स में शाब्दिक '{}' वर्णों से बचने से मदद मिल सकती है। वे तकनीकी रूप से मेटा वर्ण हैं और पीसीआरई अनचाहे घुंघराले ब्रेसिज़ के बहुत क्षमा कर रहे हैं, लेकिन यदि आप उन्हें ठीक से बचते हैं तो यह कम काम कर सकता है। इसके अलावा नामित कैप्चर समूह का उपयोग क्यों करें और पीछे संदर्भों में नामों का उपयोग न करें? '/ block: \ 3' =>'/block :(? पी = नाम) '। ' 'के बाद यह आपके रेगेक्स के लिए विशेष रूप से सच है, जिस मामले में' '\ 2' होगा, \ \ 3' –
DaveRandom