2009-03-29 12 views
10

मूल रूप से एक प्रश्न था जिसे मैं पूछना चाहता था, लेकिन सवाल के विवरणों की खोज करते समय मुझे समाधान मिला और सोचा कि यह दूसरों के लिए ब्याज हो सकता है।नियमित अभिव्यक्ति जो उद्धृत उद्धरणों के बीच मेल खाता है, जिसमें

अपाचे में, पूर्ण अनुरोध दोहरे उद्धरण में है और किसी भी कोट के अंदर हमेशा एक बैकस्लैश के साथ भाग रहे हैं:

1.2.3.4 - - [15/Apr/2005:20:35:37 +0200] "GET /\" foo=bat\" HTTP/1.0" 400 299 "-" "-" "-" 

मैं एक regex जो सभी अलग क्षेत्रों से मेल खाता है का निर्माण करने की कोशिश कर रहा हूँ।

^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"[^"]+"\s+(\d+)\s+(\d+|-) 

मुझे लगता है कि मैं भी टिप्पणी के साथ मेरी पीएचपी स्रोत से मेरी समाधान उपलब्ध कराएँगे: मेरे वर्तमान समाधान हमेशा GET/POST (वास्तव में मैं केवल आकार का तबादला सहित सभी मूल्यों की आवश्यकता) के बाद पहली बोली पर बंद हो जाता है और बेहतर स्वरूपण:

$sPattern = ';^' . 
    # ip address: 1 
    '(\d+\.\d+\.\d+\.\d+)' . 
    # ident and user id 
    '\s+[^\s]+\s+[^\s]+\s+' . 
    # 2 day/3 month/4 year:5 hh:6 mm:7 ss +timezone 
    '\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]' . 
    # whitespace 
    '\s+' . 
    # request uri 
    '"[^"]+"' . 
    # whitespace 
    '\s+' . 
    # 8 status code 
    '(\d+)' . 
    # whitespace 
    '\s+' . 
    # 9 bytes sent 
    '(\d+|-)' . 
    # end of regex 
    ';'; 

एक सरल मामले में जहां यूआरएल अन्य उद्धरण शामिल नहीं है के साथ इस का उपयोग ठीक काम करता है:

1.2.3.4 - - [15/Apr/2005:20:35:37 +0200] "GET /\ foo=bat\ HTTP/1.0" 400 299 "-" "-" "-" 

अब मैं किसी के लिए समर्थन प्राप्त करने की कोशिश नहीं कर रहा हूं, इसमें \" की एक या अधिक घटनाएं हैं, लेकिन समाधान नहीं मिल रहा है।

^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"(.|\\(?="))*" 

यहाँ केवल बदला हिस्सा:

# request uri 
    '"(.|\\(?="))*"' . 

हालांकि, यह भी लालची है regexpal.com का उपयोग करते हुए मैं इस के साथ आया गया है अब तक। यह पिछले " तक सबकुछ खाता है, जब इसे केवल " तक \ से पहले नहीं खाना चाहिए। मैं भी आवश्यकता नहीं है कि " मैं चाहता हूँ से पहले कोई \ शुरू करने की कोशिश की, लेकिन यह अभी भी स्ट्रिंग के अंत करने के लिए खाता है (ध्यान दें: मैं PHP में इस काम करने के लिए बाहरी \ वर्ण जोड़ने के लिए था):

# request uri 
    '"(.|\\(?="))*[^\\\\]"' . 
* ?:? यदि , +, या {} परिमाणकों में से किसी के तुरंत बाद इस्तेमाल किया, बनाता है परिमाणक गैर लालची (बार की न्यूनतम संख्या से मेल खाते)

# request uri 
    '"(.|\\(?="))*?[^\\\\]"' . 

लेकिन तब यह मुझे मारा

पूर्ण regex:

^(\d+\.\d+\.\d+\.\d+)\s+[^\s]+\s+[^\s]+\s+\[(\d+)/([A-Za-z]+)/(\d+):(\d+):(\d+):(\d+)\s+\+\d+\]\s+"(.|\\(?="))*?[^\\]"\s+(\d+)\s+(\d+|-) 

अद्यतन 5 वीं मई 2009:

मैं लाइनों के लाखों लोगों को पार्स कारण regexp में एक छोटे से दोष की खोज की: यह लाइनों जो सही डबल से पहले बैकस्लैश वर्ण पर टूट जाता है बोली। दूसरे शब्दों में:

...\\" 

रेगेक्स तोड़ देगा। अपाचे ...\" लॉग नहीं करेगा लेकिन हमेशा बैकस्लैश से \\ पर बच जाएगा, इसलिए यह मानना ​​सुरक्षित है कि डबल कोट से पहले दो बैकस्लैश वर्ण होते हैं।

किसी को भी यह पता है कि इसे रेगेक्स के साथ कैसे ठीक किया जाए?

उपयोगी संसाधन: the JavaScript Regexp documentation at developer.mozilla.org और regexpal.com

उत्तर

26

इस प्रयास करें:

"(?:[^\\"]+|\\.)*" 

यह नियमित अभिव्यक्ति एक दोहरे उद्धरण चरित्र \ और " के अलावा अन्य या तो किसी भी चरित्र का एक अनुक्रम या एक भाग निकले अनुक्रम के बाद से मेल खाता है \α (जहां α कोई भी चरित्र हो सकता है) f अंतिम डबल कोट चरित्र द्वारा अनुमोदित। (?:expr) वाक्यविन्यास सिर्फ एक गैर-कैप्चरिंग समूह है।

+2

क्या आप सभी के लाभ के लिए अपने रेगेक्स के बारे में कुछ और जानकारी जोड़ सकते हैं? मैं मुश्किल से समझने में कामयाब रहा कि मैंने क्या लिखा ... धन्यवाद :) – mark

+5

(?: ए | बी) ए या बी से मेल खाता है \\। न्यूलाइन को छोड़कर किसी भी चरित्र के बाद बैकस्लैश से मेल खाता है। [^ \\ "] बैकस्लैश और डबल कोट को छोड़कर किसी भी चरित्र से मेल खाता है। इसे एक साथ रखकर आप जो चाहते हैं वह ठीक है, +1। –

+0

सुंदर ... धन्यवाद आदमी। –

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