2012-06-21 15 views
7

जिस वेबसाइट पर मैं काम कर रहा हूं वह एक PHP (preg_match) regex पैटर्न का उपयोग करके डेटा से मेल नहीं खाएगा जो हर जगह काम करने लगता है मैंने इसका परीक्षण किया है। वह पैटर्न है:क्या ये रेगेक्स पैटर्न अलग हैं?

<channel.*?>(.*?)</channel> 

यह एक आरएसएस फ़ीड के खिलाफ मेल खाता है जिसमें एक चैनल टैग है।

अब सर्वर मैं पर काम कर रहा हूँ केवल सही परिणाम का उत्पादन करेगा अगर करने के लिए यह परिवर्तन:

<channel.*?>(.*)?</channel> 

मेरे regex दुनिया में नहीं सबसे अच्छा तो मैं अगर कोई मुझे बता सकते हैं अगर सोच रहा हूँ है दो पैटर्न के बीच कोई महत्वपूर्ण अंतर है।

छोटा नोट: मुझे एहसास है कि यह शायद सरलXML आदि का उपयोग करना बेहतर होगा, लेकिन यह रेगेक्स पिछले एप्लिकेशन से है और विभिन्न कारणों से मुझे इसे बदलने की अनुमति नहीं है।

किसी भी अंतर्दृष्टि के लिए अग्रिम धन्यवाद।

+2

' '' अपने PCRE सीमांकक है? यदि ऐसा है, तो 's' संशोधक एक अंतर कर सकता है या नहीं (मुझे पूरी तरह से यकीन नहीं है)। – BoltClock

+0

हां ''पीसीआर डिलीमीटर है। इसका उपयोग मूल रूप से कोड लिखने वाले व्यक्ति द्वारा किया जाता था, आमतौर पर '#' या '~' का उपयोग करते थे। – Vunus

उत्तर

7

कथन (.*) कहता है "चयन शून्य या अधिक वर्ण है" और पिछला ? इसे वैकल्पिक मिलान बनाता है। इसके विपरीत, (.*?) एक "आलसी सितारा" (*?) का उपयोग कर रहा है जो पहले मैच को पूरी तरह से छोड़ने का प्रयास करता है। अधिक जानकारी के लिए this देखें।

एक सामान्य (लालची) सितारा और आलसी स्टार के बीच के अंतर को समझने के लिए, PHP में निम्नलिखित उदाहरण देखें और ध्यान दें कि लालची सितारा यह पैटर्न के साथ सबसे बड़ा मैच बनाता है, जबकि आलसी तारा "देता है" जैसे ही यह मेल खाने वाला पैटर्न संतुष्ट है:

$inputs = array('axb' , 'axxxb' , 'axbxb' , 'axbxxxb'); 

// GREEDY STAR (NORMAL) 
foreach($inputs as $input) 
{ 
    preg_match('/a.*b/' , $input , $greedy); 
    $greedy_matches[] = $greedy[0]; 
} 

print "<pre>"; 
print_r($greedy_matches); 
print "</pre>"; 
/* 
Array 
(
    [0] => axb 
    [1] => axxxb 
    [2] => axbxb 
    [3] => axbxxxb 
) 
*/ 



// LAZY STAR 
foreach($inputs as $input) 
{ 
    preg_match('/a.*?b/' , $input , $lazy); 
    $lazy_matches[] = $lazy[0]; 
} 

print "<pre>"; 
print_r($lazy_matches); 
print "</pre>"; 
/* 
Array 
(
    [0] => axb 
    [1] => axxxb 
    [2] => axb 
    [3] => axb 
) 
*/ 
+0

धन्यवाद। इससे बड़ी राशि में मदद मिली है (उत्तर देने वाले सभी के लिए धन्यवाद)। मेरे पास एक छोटा सा सवाल यह है कि मूल रूप से वहां मौजूद कोड '(। *?)' मेरे सर्वर सहित हर जगह ठीक काम करता प्रतीत होता है, लेकिन यह एकल सर्वर केवल '(। *)?' के साथ लगातार काम करता है। क्या यह "आलसी सितारा" की वजह से है या क्या यह उस सर्वर के बारे में कुछ अजीब हो सकता है और यह रेगेक्स मिलान है? – Vunus

+0

आलसी सितारा पर्ल, आईआईआरसी से आता है, इसलिए यह मामला हो सकता है कि यह विशेष सर्वर रेगेक्स लाइब्रेरी का उपयोग कर रहा है जिसमें आलसी स्टार लागू नहीं है। –

+0

बस चेक किया गया है और मेरे संस्करण में पर्ल का एक अलग संस्करण है, इसलिए मुझे सबसे अच्छा स्पष्टीकरण मिल गया है। धन्यवाद। – Vunus

-1

नियमित अभिव्यक्ति में, * 0 या अधिक बार का मतलब है - जोड़ने के लिए कोई जरूरत नहीं है? इसके बाद।

संपादित करें: के रूप में मैं अब टिप्पणियों से समझते हैं, लालची फर्क नहीं पड़ता। एक छोटी सी परीक्षण का मामला:

var_dump(preg_replace('/<channel.*?>(.*?).*<\/channel>/', '$1', '<channel>asd</channel>')); 
var_dump(preg_replace('/<channel.*?>(.*)?.*<\/channel>/', '$1', '<channel>asd</channel>')); 

आउटपुट

string(0) "" 
string(3) "asd" 

जैसा कि आप देख, मैं (.*?).* और (.*)?.* का उपयोग कर रहा है, ताकि लालची जा रहा है फर्क होगा। लेकिन, जैसा कि यह वही नहीं है, दिए गए उदाहरण में मैं नहीं देखता कि इससे अंतर कैसे हो सकता है।

+3

'*? 'एक असभ्य शून्य-या-अधिक मात्रात्मक है। –

2

मेरा अनुमान है कि आप वास्तव में ऑपरेटर को आलसी होना नहीं चाहते हैं। एक आलसी ऑपरेटर आम तौर पर जितना संभव हो सके मिलान करने की कोशिश करेगा, जो अनियमित हो सकता है कि बहुत से डेटा से निपटने के दौरान अप्रत्याशित परिणाम दे सकते हैं। लालची समूह के अंत में प्रश्न चिह्न डालकर आप लालची समूह में एक वैकल्पिक मैच जोड़ते हैं, क्योंकि समूह को गैर लालची (आलसी) बनाने के विरोध में। यदि आप लालची और आलस्य के बीच भेद के बारे में अधिक पढ़ना चाहते हैं तो इसे देखें: http://www.regular-expressions.info/possessive.html

0

कृपया उस पाठ का एक उदाहरण प्रदान करें जिसके खिलाफ आप मिलान करने का प्रयास कर रहे हैं।

'<channel.*' will match anything starting with <channel 

'?>' will match a single character followed by > (so '1>', '2>', 'b>' etc) 

आप के बीच सब कुछ मिलान करना चाहते हैं तो बस पैटर्न का उपयोग

'#<channel>(.*)</channel>#' 
संबंधित मुद्दे