2011-12-27 13 views
10

पैटर्न मुझे इस कोड को चलाने के साथ चाल निभाता है, मैं "नहीं" बाहर मुद्रित:पर्ल एक 'स्मृति फ़ाइल' के लिए लेखन मिलान

my $memory_file; 
my $fh; 
open ($fh, '>', \$memory_file); 
print $fh "abc"; 
if($memory_file =~ m/^.*$/) 
{ print "yes\n" } 
else 
{ print "no\n" } 

अगर मैं $memory_file प्रिंट आउट, सामग्री वास्तव में कर रहे "abc"

यदि मैं पैटर्न को .* (^ या $) में बदलता हूं तो यह अपेक्षा के अनुसार काम करता है।

अगर मैं मैच से पहले लाइन $memory_file = "abc" शब्दों में कहें, मैं 'हां' बाहर मुद्रित (मूल रूप से उम्मीद के रूप में)।

क्या पृथ्वी पर यहाँ पर चल रहा है?PerlMonks पर कुछ और चर्चा:

अद्यतन (यह पर्ल 5.14.1 है)। यह एक बग की तरह प्रतीत होता है, मैं इसे लॉग कर दूंगा।

अद्यतन 2: ठीक पर्ल डेवलपर्स इस बग तय कर दी है: https://rt.perl.org/rt3//Public/Bug/Display.html?id=108398

+1

यह एक बग की तरह लगता है: http://perldoc.perl.org/perlbug.html ('perldoc perlbug') – toolic

उत्तर

4

यह पंक्ति चरित्र का अंत है जो चीजों को गड़बड़ कर रहा है। एक नियमित असाइनमेंट काम करता है:

my $str = "abc"; 
print "Works" if $str =~ /^.*$/; 

... प्रश्न में कोड नहीं है। यह regex किसी भी स्ट्रिंग से मेल खाना चाहिए, क्योंकि यह खाली स्ट्रिंग से भी मेल खाता है। यहां तक ​​कि अपरिभाषित मान भी मेल खाते हैं (हालांकि यह चेतावनी देगा)। इसके अलावा, ^.* मेल खाता है।

एकमात्र उचित स्पष्टीकरण यह है कि किसी कारण से, स्ट्रिंग के अंत से मेल खाने के लिए जो भी जांच की जाती है, उसे नहीं मिल रहा है। स्ट्रिंग का अंत गुम है।

उत्सुकता से, $\z कार्यों के साथ बदलकर काम करता है। लेकिन \Z नहीं।

एक नई लाइन भी जोड़ना काम करता है। जो एक नई लाइन जोड़ने के रूप में समझ में आता है, यह दर्शाता है कि गैर-मल्टीलाइन रेगेक्स भावना में स्ट्रिंग का अंत भी जोड़ा जाता है।

मुझे ऐसा क्यों होता है, यह आंतरिक कार्य नहीं जानता है, लेकिन मुझे संदेह है कि इस "असाइनमेंट" के इस विशेष रूप का उपयोग करते समय, स्ट्रिंग पर एक एंड-द-स्ट्रिंग मार्कर कभी नहीं रखा जाता है। एक प्रकार का "कच्चा" असाइनमेंट, जो रेगेक्स में स्ट्रिंग के अंत के लिए चेक को भ्रमित करता है।

यह एक बग की तरह लगता है। शायद यह विशेष सुविधा ठीक से बनाए रखा नहीं गया है।

+0

बस के लिए एक और डेटा प्वाइंट, '' abc \ n "' को mem फ़ाइल में प्रिंट करना और '^। * \ n $' के विरुद्ध मिलान करना भी विफल रहता है (लेकिन 'सामान्य' तारों के साथ सफल होता है)। '^। * $' सफल होने के साथ 'abc \ n" 'मिलान करना, जैसा कि कहीं और उल्लेख किया गया है। – jwd

0

ठीक है, मेरी पहली वृत्ति कहना है कि स्मृति में फ़ाइलों को शारीरिक फ़ाइलों के रूप में एक ही कार्रवाई नहीं करते है। यह देखने के लिए कि आपका इनपुट 'लाइन' बनता है या नहीं, यह देखने के लिए print $fh "abc"; से print $fh "abc\n"; को बदलने का प्रयास करें।

मेरे अन्य वृत्ति है कि आपकी फ़ाइल वास्तव में इससे पहले कि आप से पढ़ने के लिए नहीं लिखा जा रहा है है। $|++;

तो साथ अपने बफर फ्लश, कोशिश:

my $memory_file; 
my $fh; 
open ($fh, '>', \$memory_file); 
print $fh "abc"; 
$|++; 
if($memory_file =~ m/^.*$/) 
{ print "yes\n" } 
else 
{ print "no\n" } 
+1

मुझे लगता है कि' $ | ++ 'एक कॉन्फ़िगरेशन सेटिंग की तरह है और इसे जल्दी सेट किया जाना चाहिए, फ्लशिंग ट्रिगर करने के लिए एक तरीके के रूप में माना जा रहा है। –

+0

क्या @PlatinumAzure ने कहा। और इसके अलावा, आपके द्वारा दिए गए कोड को चलाने से मेरे सिस्टम पर 'नो' प्रिंट भी होता है। क्या यह आपके लिए अलग है? – jwd

+3

'$ | = 1; 'ऑटोफ्लैश STDOUT। (तहखाने में, वर्तमान में 'चयनित' हैंडल।) आप '$ fh-> autoflush (1); 'इसके बजाय चाहते हैं। – ikegami

2

मुझे लगता है कि समस्या न्यू लाइन और $ लंगर है। यह नई लाइन के बाद स्ट्रिंग की जांच करता है और आपकी स्ट्रिंग में यह नहीं है।

संपादित:

अन्य उत्तर में समस्या का एक विस्तार व्याख्या देखें क्योंकि मेरा गलत था। लेकिन मैं दो विकल्प इसे हल करने दे देंगे:

  • लिखें अपनी फ़ाइल को "abc \ n" और \z साथ स्ट्रिंग के $
  • चेक अंत के साथ की जाँच करें।
+0

यह गलत है। '$ लाइन के अंत से मेल खाता है (या अंत में नई लाइन से पहले) 'देखें [perlre] (http://perldoc.perl.org/perlre.html#Metacharacters)। – TLP

+0

और यहां तक ​​कि यदि यह सही था, '* * 'मैचों * किसी भी * स्ट्रिंग, क्योंकि यह खाली स्ट्रिंग से भी मेल खाता है। – TLP

+0

@ टीएलपी: आप सही हैं। भ्रम से बचने के लिए मैं अपना जवाब हटा दूंगा। – Birei

2

सिर्फ एक सहायक चर का उपयोग करें।

#$| = 1; # AutoFlush 

my $memory_file; 
open (my $fh, '>>', \$memory_file) or die $!; 
print $fh "abc"; 

my $buff = $memory_file; 

if($buff =~ m/^abc$/){ # or m/^.*$/ 
    print "yes\n"; 
}else{ 
    print "no\n"; 
} 
+0

यह बिना किसी समझौते के काम करता है: 'मेरा $ buff = $ memory_file'। – TLP

+0

बिल्कुल! बस एक सहायक चर का उपयोग करें। – killzone

+0

इसे अस्थायी चर में संग्रहीत करना वास्तव में काम करता है, इसलिए इसके लिए धन्यवाद। क्या आपके पास इस व्यवहार के लिए कोई आसान स्पष्टीकरण है? – jwd

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