2012-07-10 8 views
12

स्ट्रिंग के लिए परिणाम "ए \ nbb \ ncc" के लिए परिणाम नहीं समझा जा सकता है, मैं अंतिम अक्षर ("ए") के अंत तक अंतिम पत्र से मिलान करना चाहता हूं बहु लाइन स्ट्रिंग और उम्मीद है कि

"aa\nbb\ncc" =~ qr/(. $ .+)/xms से मेल खाता है a\nbb\ncc

और उस

"aa\nbb\ncc\n" =~ qr/(. $ .+)/xms मैचों a\nbb\ncc\n

लेकिन मैं "aa\nbb\ncc" =~ qr/(. $ .+)/xms के लिए कोई मुकाबला नहीं मिला है और "aa\nbb\ncc" =~ qr/(. $ .+)/xms के लिए c\n मेल खाते हैं।

qr/(. $ ..+)/xms का उपयोग करके मुझे अपेक्षित परिणाम मिल गए (उदाहरण कोड देखें)।

पर्ल संस्करण 5.14.2।

क्या कोई उस व्यवहार के लिए स्पष्टीकरण दे सकता है?

perldoc perlre:

m Treat string as multiple lines. That is, change "^" and "$" 
     from matching the start or end of the string to matching the start 
     or end of any line anywhere within the string. 

    s Treat string as single line. That is, change "." to match any character 
     whatsoever, even a newline, which normally it would not match. 

     Used together, as "/ms", they let the "." match any character whatsoever, 
     while still allowing "^" and "$" to match, respectively, just after and 
     just before ewlines within the string. 

    \z Match only at end of string 

निम्न उदाहरण कोड चल रहा है:

#!/usr/bin/env perl 

use strict; 
use warnings; 

print "Multiline string : ", '"aa\nbb\ncc"', "\n\n"; 
my $str = "aa\nbb\ncc"; 

print_match($str, qr/(. $)/xms);  # matches "a" 
print_match($str, qr/(. $ .)/xms);  # matches "a\n" 
print_match($str, qr/(. $ ..)/xms); # matches "a\nb" 
print_match($str, qr/(. $ ..+)/xms); # matches "a\nbb\ncc" 
print_match($str, qr/(. $ .+)/xms); # NO MATCH ! Why ??? 
print_match($str, qr/(. $ .+ \z)/xms); # NO MATCH ! Why ??? 

print "\nMultiline string now with terminating newline : ", '"aa\nbb\ncc\n"', "\n\n"; 
$str = "aa\nbb\ncc\n"; 

print_match($str, qr/(. $)/xms);  # matches "a" 
print_match($str, qr/(. $ .)/xms);  # matches "a\n" 
print_match($str, qr/(. $ ..)/xms); # matches "a\nb" 
print_match($str, qr/(. $ ..+)/xms); # matches "a\nbb\ncc\n" 
print_match($str, qr/(. $ .+)/xms); # MATCHES "c\n" ! Why ??? 
print_match($str, qr/(. $ .+ \z)/xms); # MATCHES "c\n" ! Why ??? 

sub print_match { 
    my ($str, $regex) = @_; 
    $str =~ $regex; 
    if ($1) { 
     printf "--> %-20s matched : >%s< \n", $regex, $1; 
    } 
    else { 
     printf "--> %-20s : no match !\n", $regex; 
    } 
} 

उत्पादन होता है:

Multiline string : "aa\nbb\ncc" 

--> (?^msx:(. $))  matched : >a< 
--> (?^msx:(. $ .)) matched : >a 
< 
--> (?^msx:(. $ ..)) matched : >a 
b< 
--> (?^msx:(. $ ..+)) matched : >a 
bb 
cc< 
--> (?^msx:(. $ .+)) : no match ! 

Multiline string now with terminating newline : "aa\nbb\ncc\n" 

--> (?^msx:(. $))  matched : >a< 
--> (?^msx:(. $ .)) matched : >a 
< 
--> (?^msx:(. $ ..)) matched : >a 
b< 
--> (?^msx:(. $ ..+)) matched : >a 
bb 
cc 
< 
--> (?^msx:(. $ .+)) matched : >c 
< 
+0

यह पर्ल में एक बग जैसा लगता है। अच्छा खोज! संबंधित: '" एक \ nb "' 'm/a $ .. \ z/ms' के बजाय' m/a $ ... \ z/ms' मिलान करता है; * लेकिन *, जब मैं क्या हो रहा है, यह जानने के लिए बिंदुओं के चारों ओर कोष्ठक जोड़ता हूं, तो यह अचानक 'm/a $ (।) (।) \ z/ms' के बजाय' m/a $ (।) से मेल खाता है (।) (।) \ z/ms'। – ruakh

+0

बल्कि अजीब। 5.12.2 में समान है। – katastrophos

उत्तर

8

यह एक बग है। perlbug कमांड लाइन को चलाकर कृपया इसकी रिपोर्ट करें।

$ perl -E'say "aa\nbb\ncc" =~ qr/(. $ .+)/xms ? ">$1<" : 0' 
0 

$ perl -E'say "aa\nbb\ncc\n" =~ qr/(. $ .+)/xms ? ">$1<" : 0' 
>c 
< 

$ perl -v 
... 
This is perl 5, version 16, subversion 0 (v5.16.0) built for x86_64-linux 
... 

जैसे तुमने कहा, वे "a\nbb\ncc" और "a\nbb\ncc\n" क्रमशः मेल खाना चाहिए। $ से संबंधित अनुकूलन हैं। ऐसा लगता है कि उनमें से एक खाता में /ms लेने में विफल रहा है।


पुनश्च — आप use re 'debug'; में रुचि हो सकती।

$ perl -Mre=debug -E'say "aa\nbb\ncc" =~ qr/(. $ .+)/xms ? ">$1<" : 0' 
Compiling REx "(. $ .+)" 
Final program: 
    1: OPEN1 (3) 
    3: SANY (4) 
    4: MEOL (5) 
    5: PLUS (7) 
    6:  SANY (0) 
    7: CLOSE1 (9) 
    9: END (0) 
anchored ""$ at 2 minlen 2 
Matching REx "(. $ .+)" against "aa%nbb%ncc" 
    0 <> <aa%nbb%ncc>   | 1:OPEN1(3) 
    0 <> <aa%nbb%ncc>   | 3:SANY(4) 
    1 <a> <a%nbb%ncc>   | 4:MEOL(5) 
            failed... 
    3 <aa%n> <bb%ncc>   | 1:OPEN1(3) 
    3 <aa%n> <bb%ncc>   | 3:SANY(4) 
    4 <aa%nb> <b%ncc>   | 4:MEOL(5) 
            failed... 
    6 <aa%nbb%n> <cc>   | 1:OPEN1(3) 
    6 <aa%nbb%n> <cc>   | 3:SANY(4) 
    7 <aa%nbb%nc> <c>   | 4:MEOL(5) 
            failed... 
Match failed 
0 
Freeing REx: "(. $ .+)" 
+0

perl 5.16.0 भी प्रभावित है। मैं एक बग रिपोर्ट भेजूंगा। मुझे 'डीबग' का उपयोग करने के लिए इंगित करने के लिए टीएनएक्स। – katastrophos

+1

[फिक्स्ड] (http://perl5.git.perl.org/perl.git/commitdiff/ac7af3f615eb56bda50bf123662b15779da26826?hp=79a3e5ea36208f2f54e36fa3a73c72808a6d0ad8) पर्ल 5.18 में – ikegami