2011-06-29 16 views
5

निकालने के लिए मैं तार है कि इन की तरह लग रही है:अजगर रेगुलर एक्सप्रेशन तारीख

{server}_{date:YYYYMMDD}{int:######} 
{server}_{date:MON DAY YYYY}{int:######} 

... प्लस अधिक, अलग तिथि प्रारूप में। साथ ही, {} ब्लॉक की कोई भी संख्या हो सकती है, और वे किसी भी क्रम में दिखाई दे सकती हैं।

मैं पाइथन 3.2 में घुंघराले ब्रेसिज़ के बीच बस "तिथि" भाग प्राप्त करने का प्रयास कर रहा हूं। तो पहली स्ट्रिंग के लिए, मैं सिर्फ "{date: YYYYMMDD}" प्राप्त करना चाहता हूं और दूसरी स्ट्रिंग के लिए मैं बस "{date: MON DAY YYYY}" चाहता हूं। "डेट" ब्लॉक के अंदर मैं चाहता हूं कि केवल वर्ण अल्फा और व्हाइटस्पेस हैं।

मेरे regex पैटर्न है:

\{date:(\w|\s)*\} 

मैं this Regex builder पर बाहर इस परीक्षण किया है, लेकिन यह मिलान के रूप में उम्मीद नहीं कर रहा है। यह पायथन पर मेरा आउटपुट है:

>>> import re 
>>> re.findall('\{date:(\w|\s)*\}', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['D', 'Y'] 
>>> re.findall('\{date:(\w|\s)*\}', '{server}_{date:MON DAY YYYY}{int:######}') 
['Y'] 

क्या कोई मुझे बता सकता है कि मेरे पैटर्न में क्या गलत है?

+0

सभी उत्तरों के लिए धन्यवाद! अब सभी के उत्तरों को देखते हुए, यह स्पष्ट है कि मैंने अपने प्रश्न में महत्वपूर्ण विवरण छोड़े। मैंने अपनी पोस्ट संपादित की और कुछ और विवरण जोड़े। – tgxiii

उत्तर

5

'(\{date:[\w\s]+\})' आप क्या चाहते हैं देता है।

1

कोशिश इस

str = '{server}_{date:MON DAY YYYY}{int:######}' 
re.findall('\{date:.*\}(?=\{)',str) 

यह इस

['{date:MON DAY YYYY}'] 

और

str = '{server}_{date:YYYYMMDD}{int:######}' 
re.findall('\{date:.*\}(?=\{)',str) 

से ये रिटर्न:

[ '{तारीख: YYYYMMDD}']:

(? = ...) से मेल खाता है, तो ... अगले से मेल खाता है, लेकिन नहीं करता है

(?=..\{) निम्नलिखित करता है किसी भी स्ट्रिंग का उपभोग नहीं करते हैं। इसे एक लापरवाह दावे कहा जाता है। उदाहरण के लिए, इसहाक (? = असिमोव) 'आइज़ैक' से मेल खाएगा, अगर उसके बाद 'असिमोव' होगा। (source)

ध्यान दें: इस केवल समारोह अगर एक और ब्लॉक {..} {date} के बाद, मुझे लगता है यह आवश्यक है, और अगर यह आपके इनपुट उपलब्ध नहीं है अमान्य हो सकता है।

>>> import re 
>>> re.findall('(\{date:[\w\s]+\})', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['{date:YYYYMMDD}', '{date:MONDAYYYYY}'] 
>>> re.findall('(\{date:[\w\s]+\})', '{server}_{date:MON DAY YYYY}{int:######}') 
['{date:MON DAY YYYY}'] 

आप केवल डेटा मान चाहते हैं, '\{date:([\w\s]+)\}' का उपयोग करें:

+0

मुझे यह उल्लेख करना चाहिए था कि {} ब्लॉक की संख्या हो सकती है, और वे किसी भी क्रम में प्रकट हो सकते हैं। मेरा बुरा, मेरा सवाल पर्याप्त विस्तृत नहीं था। हालांकि मैं जवाब की सराहना करता हूं। – tgxiii

+0

अच्छी तरह से, यह अभी भी उस ब्लॉक को मिलेगा जो '{date:। *]' से शुरू होता है जब तक कि कोई अन्य ब्लॉक इसका अनुसरण न करे। – matchew

0
'{server}_({date:.+?}){int:' 
पर्याप्त

या, हो सकता है बेहतर

'(?<={server}_)({date:.+?})(?={int:)' 
2
>>> re.findall('\{date:([\w\s]*)\}', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['YYYYMMDD', 'MONDAYYYYY'] 
0

पूरे regex के चारों ओर एक कैप्चरिंग समूह का उपयोग करें, और (\w|\s) भाग के लिए एक गैर पर कब्जा समूह:

(\{date:(?:\w|\s)*\})

कि परिणामस्वरूप आप चाहते हैं आउटपुट:

>>> re.findall('(\{date:(?:\w|\s)*\})', '{server}_{date:MON DAY YYYY}{int:######}') 
['{date:MON DAY YYYY}'] 
>>> re.findall('(\{date:(?:\w|\s)*\})', '{server}_{date:YYYYMMDD}{date:MONDAYYYYY}{int:######}') 
['{date:YYYYMMDD}', '{date:MONDAYYYYY}'] 
+0

यदि आप गैर-कैप्चरिंग समूह का उपयोग करते हैं तो पूरे रेगेक्स के आसपास ब्रांड्स को रखना वास्तव में आवश्यक नहीं है। ''{{दिनांक: (?: \ w | \ s) * \}' 'वही परिणाम उत्पन्न करता है। – senderle

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