2010-06-28 13 views
5

मैं एक नियमित अभिव्यक्ति का उपयोग कर इनपुट स्ट्रिंग को पार्स करने की कोशिश कर रहा हूं। दोहराने वाले समूह को पकड़ने की कोशिश करते समय मुझे समस्या हो रही है। मैं हमेशा समूह के आखिरी उदाहरण से मेल खाता प्रतीत होता हूं। मैंने अनिच्छुक (गैर लालची) क्वांटिफायर का उपयोग करने की कोशिश की है, लेकिन मुझे कुछ याद आ रहा है। क्या कोई मदद कर सकता है?बूस्ट :: regex_search के साथ दोहराने वाले समूह के सभी मैचों को कैप्चर कैसे करूं?

नियमित अभिव्यक्ति की कोशिश की:

(OS)\\s((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/{0,1}){1,5}?\\r 

(OS)\\s((\\w{3}?)(([A-Za-z0-9]{2}?)|(\\w{3}?)(\\w{3}?))\\/{0,1}?){1,5}?\\r 

इनपुट स्ट्रिंग:

OS BENKL/LHRBA/MANQFL\r\n 

मैं हमेशा पिछले समूह जो MANQFL समूह (MAN QFL) है, और मेरे उद्देश्य सभी तीन समूहों प्राप्त करने के लिए है पाने के लिए लग रहे हैं (वहाँ कर सकते हैं 1-5 हो समूहों):

(BEN KL) , (LHR BA) and (MAN QFL). 

सी ++ कोड स्निपेट:

std::string::const_iterator start = str.begin(), end = str.end(); 
while(regex_search(start,end,what,expr)) 
{ 
    cout << what[0]; 
    cout << what[1]; 
    ... 
    start += what.position() + what.length(); 
} 

यह लूप केवल एक बार निकलता है, जबकि मुझे उम्मीद है कि यह इस उदाहरण में 3 बार चलने की उम्मीद है। किसी भी प्रकार के मदद की बहुत सराहना की जाएगी।

+0

यदि आप हमें इनपुट के प्रारूप के बारे में और बताएंगे कि आप इसे कैसे पार्स करना चाहते हैं तो यह बहुत मदद करेगा। –

+0

इनपुट स्ट्रिंग स्ट्रीम है, और इस उदाहरण में मुझे 3 समूह (बेन केएल), (एलएचआर बीए) और (मैन क्यूएफएल) प्राप्त करने की उम्मीद है। मुझे इस मामले में पता है कि हम नियमित अभिव्यक्तियों का उपयोग किए बिना भी कर सकते हैं, लेकिन मैं यह देखने की कोशिश कर रहा हूं कि क्या मैं इसे मौजूदा कोड के साथ संगत रख सकता हूं जहां रेगेक्स का उपयोग किया जाता है। – omshanti

उत्तर

0

यह अपेक्षित व्यवहार है: जब एक कैप्चरिंग समूह को क्वांटिफायर द्वारा नियंत्रित किया जाता है, तो प्रत्येक पुनरावृत्ति पिछली बार जो भी कब्जा कर लिया गया था उसे ओवरराइट करता है। सबसे आसान तरीका मैचों के सभी प्राप्त करने के लिए इस तरह, पूरी बात के चारों ओर एक कैप्चरिंग समूह डाल करने के लिए होगा:

(OS)\\s(((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/?){1,5})\\r 

समूह BENKL/LHRBA/MANQFL, जो आप / पर विभाजित कर सकते हैं युक्त खत्म हो जाएगा कि।

1

एकमात्र रेगेक्स स्वाद जो मुझे पता है जो आपको कैप्चरिंग समूह के सभी पुनरावृत्तियों को दे सकता है वह .NET Regex स्वाद है। आम तौर पर एक रेगेक्स इंजन केवल प्रत्येक कैप्चरिंग समूह के अंतिम पुनरावृत्ति को बचाता है।

इस तरह की समस्या का सामान्य समाधान समूह के सभी पुनरावृत्तियों को पकड़ने के लिए एक रेगेक्स का उपयोग करना है, और दूसरे रेगेक्स को अलग-अलग वस्तुओं में पहले रेगेक्स के परिणाम को विभाजित करने के लिए है। एलन ने पहले ही समझाया है कि आप इस विशेष स्थिति में यह कैसे कर सकते हैं।

4

बूस्ट :: रेगेक्स से कई मैचों को प्राप्त करने का सबसे अच्छा तरीका regex_iterators का उपयोग करना है। यह उदाहरण आपको जो चाहिए वो करना चाहिए।

#include <iostream> 
#include <string> 
#include <boost/regex.hpp> 

int main() { 
    std::string a = "OS BENKL/LHRBA/MANQFL\r\n"; 
    const boost::regex re("[A-Z]{3}[A-Z]*"); 
    boost::sregex_iterator res(a.begin(),a.end(),re); 
    boost::sregex_iterator end; 
    for (; res != end; ++res) 
     std::cout << (*res)[0] << std::endl; 
} 
0

दोहराया कैप्चर के बारे में यहाँ अनुभाग पढ़ें: http://www.boost.org/doc/libs/1_47_0/libs/regex/doc/html/boost_regex/captures.html

असल में, क्या आप चाहते हैं एक प्रायोगिक सुविधा है अपने regex_search कॉल करने के लिए उपयुक्त #defines और झंडे को पारित करके सक्रिय किया जा सकता है।

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