2013-06-24 6 views
5

मैं किसी रेगेक्स के साथ ब्रैकेट के बाहर किसी भी पाठ को पकड़ने की कोशिश कर रहा हूं।रीजिक्स ब्रैकेट के बाहर सभी पाठ प्राप्त करने के लिए

उदाहरण स्ट्रिंग

जोसी स्मिथ [3996 कॉलेज एवेन्यू, SOMETOWN, एमडी 21003] Mugsy कुत्ता स्मिथ [2560 ओक अनुसूचित जनजाति, GLENMEADE, WI 14,098]

मैं कर सकती हूं पाठ के अंदर स्क्वायर ब्रैकेट सफलतापूर्वक प्राप्त करने के लिए:

addrs = re.findall(r"\[(.*?)\]", example_str) 
print addrs 
[u'3996 COLLEGE AVENUE, SOMETOWN, MD 21003',u'2560 OAK ST, GLENMEADE, WI 14098']  

लेकिन मुझे स्क्वायर ब्रैकेट के के बाहर कुछ भी परेशानी हो रही है।

names = re.findall(r"(.*?)\[.*\]+", example_str) 

लेकिन यह है कि केवल प्रथम नाम पाता है:

print names 
[u'Josie Smith '] 

अब तक मैं केवल एक स्ट्रिंग दो name [address] कॉम्बो करने के लिए एक से युक्त देखा है, लेकिन मैं मैं निम्नलिखित की तरह कुछ की कोशिश की है मैं मानता हूं कि उनमें से कोई भी स्ट्रिंग में हो सकता है। सभी कि एक उद्घाटन वर्ग कोष्ठक वर्ग कोष्ठकों में कुछ या स्ट्रिंग

+1

ब्रैकेट को नेस्टेड किया जा सकता है – aaronman

+0

@Aaronman मुझे लगता है कि कोई नेस्टेड ब्रैकेट नहीं होगा। अच्छा प्रश्न। – Banjer

उत्तर

7

के अंत के बाद कोई नेस्टेड कोष्ठक नहीं हैं, तो नहीं है:

+0

क्या होगा यदि ब्रैकेट की आखिरी जोड़ी * के बाद * कोई पाठ है? (केवल आपके रेगेक्स का जिक्र है; आपका विभाजन समाधान काम करता है) –

+0

आह हाँ, यह सब समझ में आता है। मुझे 'स्प्लिट' समाधान बेहतर लगता है। – Banjer

+0

@ टिमपेट्ज़कर: आप इसे ओपी के मूल रेगेक्स के समान शैली में जोड़ सकते हैं; थोड़ा जटिल यह है कि इसे लिखने का स्पष्ट तरीका एक गैर-कैप्चरिंग समूह की आवश्यकता है। कैसे दिखाने के लिए जवाब संपादित किया। – abarnert

1

आप यह कर सकते हैं:

outside = re.findall(r"[^[]+(?=\[[^]]*]|$)", example_str) 

दूसरे शब्दों में , तो आप सिर्फ यह कर सकते हैं:

re.findall(r'(.*?)\[.*?\]', example_str) 

हालांकि, अगर आप भी वास्तव में एक regex वह की जरूरत नहीं है कर रहे हैं। बस कोष्ठक पर विभाजित:

(s.split(']')[-1] for s in example_str.split('[')) 

एकमात्र कारण आपके प्रयास काम नहीं किया:

re.findall(r"(.*?)\[.*\]+", example_str) 

... है कि आप, कोष्ठकों के भीतर एक गैर लालची मैच कर रहे थे जो इसका मतलब है ब्रैकेट की पहली जोड़ी को कैप्चर करने के बजाय, पहले खुले ब्रैकेट से आखिरी बंद ब्रैकेट तक सब कुछ कैप्चर कर रहा था।


इसके अलावा, + अंत में गलत लगता है। यदि आपके पास 'abc [def][ghi] jkl[mno]' था, तो क्या आप ['abc ', '', ' jkl'], या ['abc ', ' jkl'] वापस प्राप्त करना चाहते हैं? यदि पूर्व, + जोड़ें नहीं। यदि यह बाद वाला है, तो करें- लेकिन फिर आपको एक गैर-कैप्चरिंग समूह में पूरे ब्रैकेट पैटर्न को रखने की आवश्यकता है: r'(.*?)(?:\[.*?\])+


अगर वहाँ पिछले ब्रैकेट के बाद अतिरिक्त पाठ हो सकता है, split विधि से कार्य करेंगे, या आप re.findall के बजाय re.split इस्तेमाल कर सकते हैं ... लेकिन उस के साथ काम करने के लिए आप अपने मूल regex समायोजित करना चाहते हैं, तो आप कर सकते हैं ।

अंग्रेजी में, आप जो चाहते हैं वह किसी भी (गैर लालची) को ब्रैकेट-संलग्न सबस्ट्रिंग या स्ट्रिंग के अंत से पहले सबस्ट्रिंग करना है, है ना?

तो, आपको \[.*?\] और $ के बीच एक विकल्प की आवश्यकता है। बेशक आपको समूह लिखने की जरूरत है ताकि विकल्प लिखने के लिए, और आप समूह को कैप्चर नहीं करना चाहते हैं। तो:

re.findall(r"(.*?)(?:\[.*?\]|$)", example_str) 
3

अगर वहाँ कभी नहीं नेस्टेड कोष्ठक हैं:

([^[\]]+)(?:$|\[) 

उदाहरण:

>>> import re 
>>> s = 'Josie Smith [3996 COLLEGE AVENUE, SOMETOWN, MD 21003]Mugsy Dog Smith [2560 OAK ST, GLENMEADE, WI 14098]' 
>>> re.findall(r'([^[\]]+)(?:$|\[)', s) 
['Josie Smith ', 'Mugsy Dog Smith '] 

स्पष्टीकरण:

([^[\]]+) # match one or more characters that are not '[' or ']' and place in group 1 
(?:$|\[) # match either a '[' or at the end of the string, do not capture 
+0

यह एक बेहतर काम करता है क्योंकि यह एक खाली स्ट्रिंग नहीं देता है जैसे @ abamert's करता है –

1

आप regex और अभी भी साथ जाने के लिए चाहते हैं नेस्टेड ब्रैकेट को संभालें, आप इसके साथ जा सकते हैं:

import re 
expr = re.compile("(?:^|])([^[\]]+)(?:\[|$)") 

print(expr.findall("myexpr[skip this[and this]]another[and skip that too]")) 

इससे ['myexpr', 'another'] मिलेगा।

विचार स्ट्रिंग की भिखारी या ] और स्ट्रिंग या [ के बीच किसी भी चीज़ से मेल खाना है।

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