2013-02-11 7 views
7

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

निम्नलिखित कोड केवल "गाय" को कैप्चर करता है और "परीक्षण; गाय" और "गाय" दोनों को याद करता है।

myList = ['test;cow', 'one', 'two', 'three', 'cow.', 'cow', 'acow'] 
myString = 'cow' 
indices = [i for i, x in enumerate(myList) if x == myString] 
print indices 
>> 5 

मैं रेगुलर एक्सप्रेशन का उपयोग करने के लिए कोड को बदलने की कोशिश की है:

import re 
myList = ['test;cow', 'one', 'two', 'three', 'cow.', 'cow', 'acow'] 
myString = 'cow' 
indices = [i for i, x in enumerate(myList) if x == re.match('\W*myString\W*', myList)] 
print indices 

लेकिन यह एक त्रुटि देता है: उम्मीद स्ट्रिंग या बफ़र

किसी को भी जानता है कि मैं गलत है कि मैं क्या कर रहा हूँ तो सुनने के लिए बहुत खुश होना चाहिए। मुझे लगता है कि यह इस तथ्य से कुछ करने के लिए है कि मैं स्ट्रिंग की अपेक्षा करते समय वहां एक नियमित अभिव्यक्ति का उपयोग करने की कोशिश कर रहा हूं। क्या कोई समाधान है?

उत्पादन मैं तलाश कर रहा हूँ पढ़ना चाहिए:

>> [0, 4, 5] 

धन्यवाद

उत्तर

14

आप match का परिणाम x वापस करने के लिए आवंटित करने के लिए जरूरत नहीं है। और आपका मैच की बजाय x पर होना चाहिए।

इसके अलावा, आपको re.match के बजाय re.search का उपयोग करने की आवश्यकता है, क्योंकि आपके रेगेक्स पैटर्न '\W*myString\W*' पहले तत्व से मेल नहीं खाएंगे। ऐसा इसलिए है क्योंकि test;\W* से मेल नहीं खाता है। दरअसल, आपको केवल तत्काल निम्नलिखित और पहले वर्ण के लिए परीक्षण करने की आवश्यकता है, न कि पूर्ण स्ट्रिंग।

तो, आप बल्कि स्ट्रिंग के आसपास word boundaries उपयोग कर सकते हैं:

pattern = r'\b' + re.escape(myString) + r'\b' 
indices = [i for i, x in enumerate(myList) if re.search(pattern, x)] 
4

वहाँ अपने कोड के साथ कुछ समस्याएं हैं। सबसे पहले, आपको संपूर्ण सूची (myList) के खिलाफ नहीं, सूची तत्व (x) के विरुद्ध expr से मिलान करने की आवश्यकता है। दूसरा, अभिव्यक्ति में एक चर डालने के लिए, आपको + (स्ट्रिंग कॉन्सटेनेशन) का उपयोग करना होगा। और अंत में, कच्चे शाब्दिक का उपयोग करें (r'\W) करने के लिए ठीक से दर्शाने expr में स्लैश:

import re 
myList = ['test;cow', 'one', 'two', 'three', 'cow.', 'cow', 'acow'] 
myString = 'cow' 
indices = [i for i, x in enumerate(myList) if re.match(r'\W*' + myString + r'\W*', x)] 
print indices 

वहाँ संभावना है कि myString (एक स्लेश या एक बिंदु की तरह) विशेष regexp वर्ण हैं कर रहे हैं, तो आप भी लागू करना होगा यह करने के लिए re.escape:

regex = r'\W*' + re.escape(myString) + r'\W*' 
indices = [i for i, x in enumerate(myList) if re.match(regex, x)] 

के रूप में टिप्पणी में कहा, निम्नलिखित एक बेहतर विकल्प हो सकता है:

regex = r'\b' + re.escape(myString) + r'\b' 
indices = [i for i, x in enumerate(myList) if re.search(regex, x)] 
+0

हो सकता है कि 're.escape' भी जोड़ सकता हूँ? –

+0

@MartijnPieters: निश्चित, जोड़ा। – georg

+0

यह पहले तत्व से मेल नहीं खाता है, जिसे ओपी मिलान करना चाहता है। –

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