2015-09-30 9 views
9

मैं एक php regex काम है कि कोष्ठक में पाठ के लिए एक स्ट्रिंग को पार्स करता है संभव नेस्टेड कोष्ठक को अनदेखा करते हुए बनाने के लिए कोशिश कर रहा हूँ अनदेखी पता लगाने के लिए:php regex कोष्ठक के अंदर का पाठ नेस्टेड कोष्ठक

चलो कहते हैं कि मैं चाहता हूँ चलो

Lorem ipsum [1. dolor sit amet, [consectetuer adipiscing] elit.]. Aenean commodo ligula eget dolor.[2. Dolor, [consectetuer adipiscing] elit.] Aenean massa[3. Lorem ipsum] dolor. 

वापस जाने के लिए

[1] => "dolor sit amet, [consectetuer adipiscing] elit." 
[2] => "Dolor, [consectetuer adipiscing] elit." 
[3] => "Lorem ipsum" 

अब तक मैं

'/\[([0-9]+)\.\s([^\]]+)\]/gi' 
मिला

लेकिन जब नेस्टेड ब्रैकेट होते हैं तो यह टूट जाता है। See demo

मैं आंतरिक ब्रैकेट का पता लगाने से कैसे अनदेखा कर सकता हूं? अग्रिम में Thx!

+0

नेस्टेड संरचना के कारण, मेरा मानना ​​है कि रेगेक्स इस मामले के लिए उपयुक्त नहीं है। शायद एक साधारण दिनचर्या एक बेहतर दृष्टिकोण है। – someOne

उत्तर

2

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

$pattern = '~\[ (?:(\d+)\.\s)? ([^][]*+ (?:(?R) [^][]*)*+) ]~x'; 

if (preg_match_all($pattern, $text, $matches)) 
    $result = array_combine($matches[1], $matches[2]); 

पैटर्न विवरण:

~  # pattern delimiter 
\[ # literal opening square bracket 
(?:(\d+)\.\s)? # optional item number (*) 
(    # capture group 2 
    [^][]*+   # all that is not a square bracket (possessive quantifier) 
    (?:    # 
     (?R)  # recursion: (?R) is an alias for the whole pattern 
     [^][]*  # all that is not a square bracket 
    )*+    # repeat zero or more times (possessive quantifier) 
) 
]     # literal closing square bracket 
~x # free spacing mode 

(*) ध्यान दें कि यदि आप (?R)के साथ रिकर्सन का उपयोग करने में सक्षम होना चाहते हैं तो आइटम नंबर भाग वैकल्पिक होना चाहिए (उदाहरण के लिए [consectetuer adipiscing] में कोई आइटम नंबर नहीं है।)। यदि आप आइटम नंबर के बिना स्क्वायर ब्रैकेट से बचना चाहते हैं तो यह समस्याग्रस्त हो सकता है। (?(R)|(\d+)\.\s)

सशर्त बयान:

(?(R)  # IF you are in a recursion 
      # THEN match this (nothing in our case) 
    |   # ELSE 
    (\d+)\.\s # 
) 

इस तरह से आइटम नंबर अनिवार्य हो जाता है में इस मामले में आप एक और अधिक मजबूत पैटर्न का निर्माण कर सकते हैं यदि आप एक सशर्त बयान के वैकल्पिक समूह (?:(\d+)\.\s)? बदल जाते हैं।

1

आप सभी सबस्ट्रिंग वर्ग कोष्ठक के साथ संलग्न प्राप्त करने के लिए एक पुनरावर्ती regex का उपयोग कर सकते हैं, और फिर एक array_map अंदर एक preg_replace का उपयोग कोष्ठक और enclosing कोष्ठक दूर करने के लिए:

$str = "Lorem ipsum [1. dolor sit amet, [consectetuer adipiscing] elit.]. Aenean commodo ligula eget dolor.[2. Dolor, [consectetuer adipiscing] elit.] Aenean massa[3. Lorem ipsum] dolor."; 
preg_match_all('/\[(?>[^\[\]]|(?R))*]/', $str, $matches); 
$res = array_map(function($el) { 
    return preg_replace('/^\[\d+\.(.*?)\s*\]$/s', '$1', $el); 
    }, 
    $matches[0]); 
print_r($res); 

देखें IDEONE demo

\[(?>[^\[\]]|(?R))*] रेगेक्स मैचों [, फिर कुछ भी [ और ] या नेस्टेड [...] संरचनाएं। regular-expressions.info पर रेगेक्स के साथ रिकर्सन के बारे में और देखें। यहां regex demo है।

अंदर preg_repace regex - ^\[\d+\.(.*?)\s*\]$ - 1 या अधिक अंकों और एक अवधि के बाद, और मैच के साथ प्रारंभिक [ से मेल खाते हैं और अंतिम वैकल्पिक खाली स्थान के (\s*) और ] को बंद करने के लिए शेष पर कब्जा ($ कर देगा सुनिश्चित करें कि स्ट्रिंग के अंत में ब्रैकेट का मिलान किया गया है)। $1 के साथ हम बाकी स्ट्रिंग को पुनर्स्थापित कर सकते हैं और इसे एक नई सरणी बनाने के लिए उपयोग कर सकते हैं। 2nd regex demo here देखें।

5

आप पिछले समूहों के लिए पुनरावर्ती संदर्भ का उपयोग कर सकते हैं:

(?<no_brackets>[^\[\]]*){0}(?<balanced_brackets>\[\g<no_brackets>\]|\[(?:\g<no_brackets>\g<balanced_brackets>\g<no_brackets>)*\]) 

See it in action

विचार अपने वांछित मैचों परिभाषित करने के लिए है या तो कोई ब्रैकेट के साथ कुछ, [] या कुछ और से घिरा हुआ है, जो एक अनुक्रम के रूप में पहले नियम के साथ कोई ब्रैकेट या संतुलित ब्रैकेट नहीं।

+0

मुझे नामित कैप्चरिंग समूहों के बारे में पता नहीं था, बहुत उपयोगी! – hm711

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