2012-05-04 15 views
12

कुछ मिनट पहले तक, मुझे विश्वास था कि Perl का $ किसी भी प्रकार की लाइन से मेल खाता है। दुर्भाग्यवश, मेरी धारणा गलत साबित हुई।

निम्न स्क्रिप्ट अंत शब्द केवल $string3 के लिए हटा देता है।

use warnings; 
use strict; 

my $string1 = " match to the end" . chr(13); 
my $string2 = " match to the end" . chr(13) . chr(10); 
my $string3 = " match to the end" .   chr(10); 

$string1 =~ s/ end$//; 
$string2 =~ s/ end$//; 
$string3 =~ s/ end$//; 

print "$string1\n"; 
print "$string2\n"; 
print "$string3\n"; 

लेकिन मैं लगभग 75% लगता है कि मैं ऐसे मामलों में जहां $ का मिलान नहीं हुआ कम से कम chr(13).chr(10) देखा है हूँ।

तो, $ परमाणु मैच क्या वास्तव में (और किस परिस्थितियों में) करता है? केवल

+3

हो सकता है कि आप 'crlf' मोड में एक फ़ाइल पढ़ रहे हों, इसलिए फ़ाइल में' chr (13) .chr (10) 'है, लेकिन जिस स्ट्रिंग के साथ आप मिलान कर रहे थे केवल' chr (10) 'था। – cjm

उत्तर

5

$ मैचों से पहले \n/chr(10) और नहीं \r/chr(13) से पहले स्थिति।

यह बहुत अक्सर एक newline चरित्र से पहले मैच के लिए (मामलों में यह समस्या उत्पन्न कर रहा नहीं कर रहा है का एक बहुत में) गलत व्याख्या की है, लेकिन यह एक "linefeed" चरित्र पहले से मेल खाता है सख्त होने के लिए, लेकिन एक गाड़ी वापसी चरित्र से पहले नहीं!

Regex Tutorial - Start and End of String or Line Anchors देखें।

+1

गोश ने न्यूलाइन सम्मेलनों को जन्म दिया। वास्तव में –

+1

। 'न्यूलाइन' चरित्र जैसी कोई चीज़ नहीं है। – Borodin

+0

@ बोरोडिन, यूनिकोड असहमत है। यू + 000 ए को कुछ नामों से जाना जाता है जिसमें लाइन फीड और नई लाइन दोनों शामिल हैं। – ikegami

12

सबसे पहले, यह इस बात पर निर्भर करता है कि /m संशोधक प्रभाव में है या नहीं।

/m सक्रिय के साथ, यह \n वर्ण या स्ट्रिंग के अंत में पहले मेल खाता है। यह (?=\n|\z) के बराबर है।

/m के बिना, यह \n वर्ण से पहले मेल खाता है यदि यह स्ट्रिंग का अंतिम अक्षर है, या स्ट्रिंग के अंत में है। यह (?=\n?\z) के बराबर है।

यह एक सामान्य न्यूलाइन से मेल नहीं खाता है। \R मेटाएक्टेक्टर (5.10.0 में पेश किया गया) यह करता है (लेकिन $ की अंत-स्ट्रिंग संपत्ति के बिना)। प्राप्त करने के लिए पिछली समकक्षों में से एक में \n के लिए \R को प्रतिस्थापित कर सकते हैं जो एक सामान्य न्यूलाइन से मेल खाता है।

ध्यान दें कि \n हमेशा chr(10) नहीं है। यह मंच पर निर्भर करता है। वर्तमान में उपयोग किए जाने वाले अधिकांश प्लेटफ़ॉर्म में \n का अर्थ है chr(10), लेकिन यह हमेशा ऐसा नहीं था। उदाहरण के लिए, पुराने मैक पर, \nchr(13) और \rchr(10) था।

+4

आपके उत्तर का उत्तरार्द्ध भ्रामक है, अगर केवल असत्य नहीं है। आंतरिक रूप से, पर्ल * हमेशा * प्लेटफॉर्म के लाइन अनुक्रम का प्रतिनिधित्व '" \ n "' के साथ करता है, जो * हमेशा * 'chr (10), या एक ASCII' LF' है। यह लिनक्स और मैक्स ओएस एक्स के लिए बाहरी फाइल में दिखाई देने के समान है, लेकिन एक अतिरिक्त आईओ परत इसे विंडोज और डॉस प्लेटफ़ॉर्म पर 'सीआर एलएफ' से और मैक ओएस v9 और पहले 'सीआर' से अनुवाद करती है। '" \ r "' 'chr (13)', या ASCII 'CR' के अलावा कभी भी कुछ नहीं रहा है। – Borodin

+0

@ बोरोडिन हालांकि, किसी को एक अलग मंच पर जेनरेट की गई फ़ाइलों से निपटने के लिए सावधान रहना चाहिए। –

+2

@ बोरीडिन, आप गलत हैं और सीजेएम सही है। मैकोज़ पर, \ n और \ r क्रमशः 0 डी और 0 ए का मिलान/उत्पादन किया जाता है। यही कारण है कि '\ r \ n' के बजाय CGI आउटपुट के लिए' x xD \ x0A' का उपयोग करने के लिए (अप्रचलित) अनुशंसाएं हैं। यदि आप जो कहते हैं वह सत्य है, तो वे दोनों बराबर होंगे। पर्लियो परतें तब भी मौजूद नहीं थीं। – ikegami

1
/$/ 
/$/m 

/(?=\n\z)|\z/ 
/(?=\n)|\z/ 

क्रमशः के बराबर हैं। \n सभी मौजूदा प्लेटफार्मों पर यू + 000 ए (लाइन फीड उर्फ ​​न्यूलाइन) से मेल खाता है।

+0

जबकि आपके समकक्ष regexs लिखित के रूप में सही हैं, मुझे लगता है कि मेरे संस्करण बेहतर हैं। चूंकि '\ z' शून्य-चौड़ाई वाला दावा है, यह वास्तव में कोई फर्क नहीं पड़ता कि यह' (? = ...) 'के अंदर है, लेकिन समूह के अंदर परिवर्तन को स्थानांतरित करके, आप इसे बड़े रेगेक्स के रूप में उपयोग कर सकते हैं- है। अपने संस्करणों के साथ, आपको '(?: (? = \ N \ z) | \ z)' '' रखने के लिए 'से अधिक विकल्प बदलने के लिए' – cjm

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