2013-11-27 3 views
6

क्या सी में गैर-लालची नियमित अभिव्यक्ति का उपयोग करने का कोई तरीका है जैसे कि पर्ल में उपयोग किया जा सकता है? मैंने कई चीजों की कोशिश की, लेकिन यह वास्तव में काम नहीं कर रहा है।पॉज़िक्स नियमित अभिव्यक्ति गैर-लालची

मैं इस समय इस regex कि एक आईपी पता है और इसी HTTP अनुरोध से मेल खाता है का उपयोग कर रहा है, लेकिन यह लालची हालांकि मैं उपयोग कर रहा हूँ * ?:

([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1

इस उदाहरण में, यह हमेशा से मेल खाता है पूरी स्ट्रिंग:

#include <regex.h> 
#include <stdio.h> 

int main() { 

    int a, i; 
    regex_t re; 
    regmatch_t pm; 
    char *mpages = "TEST 127.0.0.1 GET /test.php HTTP/1.1\" 404 525 \"-\" \"Mozilla/5.0 (Windows NT HTTP/1.1 TEST"; 

    a = regcomp(&re, "([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1", REG_EXTENDED); 

    if(a!=0) 
     printf(" -> Error: Invalid Regex"); 

    a = regexec(&re, &mpages[0], 1, &pm, REG_EXTENDED); 

    if(a==0) { 

     for(i = pm.rm_so; i < pm.rm_eo; i++) 
      printf("%c", mpages[i]); 
     printf("\n"); 
    } 
    return 0; 
} 

$ ./regtest

127.0.0.1 प्राप्त /test.php HTTP/1.1 "404 525" - "" Mozilla/5.0 (Windows NT HTTP/1.1

+1

में इस मैक्रो आप सवाल का इनपुट स्ट्रिंग को जोड़ सकते हैं नहीं है। [यह मेरे लिए काम करता प्रतीत होता है।] (Http://regexr.com?37cvn) – OGHaza

+1

मुझे नहीं पता कि 'सी' इसलिए सलाह नहीं दे सकता है, लेकिन समस्या आपके कोड में है [आपके regex नहीं] (http: //regexr.com?37cvt)। यदि आप अपनी इनपुट स्ट्रिंग के अंत में और जोड़ते हैं तो शायद यह स्पष्ट हो जाएगा कि यह दूसरे 'HTTP/1.1' से मेल नहीं खाता बल्कि पूरे इनपुट स्ट्रिंग को वापस कर रहा है। – OGHaza

+0

आप एक अधिक सटीक आईपी मिलान का उपयोग कर सकते हैं। यह उत्तर देखें: http://stackoverflow.com/a/106223/363573 – Stephan

उत्तर

5

नहीं, POSIX नियमित अभिव्यक्तियों में कोई गैर लालची क्वांटिफायर नहीं हैं। लेकिन एक पुस्तकालय है जो सी: http://www.pcre.org/

0

जैसा कि मैंने पहले टिप्पणी में कहा था, POSIX regexes के साथ परीक्षण चलाने के लिए grep -E का उपयोग करें, इस तरह विकास समय में सुधार किया जाएगा। किसी भी तरह से, ऐसा लगता है कि यह आपकी अनुपस्थिति के बजाय नियमित अभिव्यक्ति के साथ है।

मैं अनुरोध से क्या हासिल करना चाहता हूं, इस बारे में बिल्कुल स्पष्ट नहीं हूं ... आपको लगता है कि आप केवल आईपी पता, HTTP क्रिया और संसाधन चाहते हैं, कोई निम्न रेगेक्स के साथ समाप्त हो सकता है।

regcomp(&re, "\\b(.?[0-9])+\\s+(GET|POST|PUT)\\s+([^ ]+)", REG_EXTENDED); 

ध्यान रखें कि कई मान्यताओं को बनाया गया है। उदाहरण के लिए, यह रेगेक्स मानता है कि आईपी पता अच्छी तरह से गठित किया जाएगा, यह HTTP क्रिया के साथ अनुरोध प्राप्त करता है या तो प्राप्त करें, पोस्ट करें, PUT। अपनी जरूरतों के अनुसार संपादित करें।

0

एक शब्द की अगली आवृत्ति से मेल करने के लिए एक regex होने का जानवर बल विधि है:

"([^H]|H[^T]|HT[^T]|HTT[^P]|HTTP{^/]|HTTP/[^1]|HTTP/1[^.]|HTTP/1\\.[^1])*HTTP/1\\.1" 

जब तक आप अपने मैच के बारे में बेहतर हो जाते हैं कर सकते हैं - जो आप कर सकते हैं: HTTP requests

हैं
Request-Line = Method SP Request-URI SP HTTP-Version CRLF 

और दाहिने मैच एम्बेडेड रिक्त स्थान पर nonterminals में से कोई भी नहीं। तो:

"[0-9]{1,3}(\\.[0-9]{1,3}){3} [^ ]* [^ ]* HTTP/1\\.1" 

जब से तुम सिर्फ़ पूर्ण अभिव्यक्ति मैच के लिए जगह का आवंटन कर रहे हैं, या पीठ में कोष्ठक डाल टुकड़े प्राप्त करने के लिए।

-1

अपने कोड में, pmregmatch_t की एक सरणी होनी चाहिए, और आपके मामले में, कम से कम 2 से 4 तत्व होना चाहिए, जिसके आधार पर आप() उप-अभिव्यक्तियों को कैप्चर करना चाहते हैं।

आपके पास केवल एक तत्व है। पहला तत्व, pm[0], जो भी पाठ आपके पूरे आरई से मेल खाता है, हमेशा मिलता है। यही वह है जिसे आप प्राप्त करेंगे। यह pm[1] है जो पहले() उप-अभिव्यक्ति (आईपी पता), और pm[3] का पाठ प्राप्त करेगा जो आपके (.*?) शब्द से मेल खाने वाला टेक्स्ट प्राप्त करेगा।

लेकिन जैसा कि ऊपर बताया गया है (Wumbley, W. Q. द्वारा) POSIX regex लाइब्रेरी गैर-लालची क्वांटिफायर का समर्थन नहीं कर सकती है।

0
a = regcomp(&re, "([0-9]{1,3}(\\.[0-9]{1,3}){3})(.*?)HTTP/1.1", REG_EXTENDED|REG_ENHANCED); 

पुराने समय

#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8 \ 
|| __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_6_0 
#define REG_ENHANCED 0400 /* Additional (non-POSIX) features */ 
#endif 
संबंधित मुद्दे