標籤:
《Perl語言入門》第15章習題第2題如下:
用 given-when 結構寫一個程式,根據輸入的數字,如果它能被3整除,就列印“Fizz”;如果它能被5整除,就列印“Bin”;如果它能被7整除,就列印“Sausage”。比如,如果輸入15,程式就應該列印“Fizz”和“Bin”,因為15可以同時被3和5整除。思考一下,可以讓程式輸出“Fizz Bin Sausage”的最小數字該是多少?
自己寫的程式如下:
#!/usr/bin/perl 2 use 5.010; 3 my $num; 4 while(chomp($num=<STDIN>)){ 5 next unless $num =~ /\A\d+\.?\d+\z/; #防止輸入的內容不是數字 6 given($num){ 7 when( not $_%3 ){ 8 print "Fizz "; 9 continue; 10 } 11 when( not $_%5 ){ 12 print "Bin "; 13 continue; 14 } 15 when( not $_%7 ){ 16 print "Sausage "; 17 continue; 18 } 19 default { print "\n";} 20 } 21 }
結果啟動並執行時候,發現輸入 3 、5 、7 ,沒有任何輸出,而輸入 15、 35 、21 之類的數字,卻可以有 “Fizz Bin”、 “Bin Sausage” 之類的輸出,怎麼回事呢?
仔細推敲,原來問題出在第5行的Regex的代碼上:
該行代碼的本意是測試輸入的內容是否為數字,如果不是數字,則進入下一次迴圈,讀取下一次的輸入;但匹配的模式中,‘\d+‘ 要求至少匹配一個數字字元,則兩個‘\d+‘則要求至少匹配兩個數字字元。於是,當輸入為 3 、 5、 7 的時候,因為是單個數字字元,因而無法正常匹配,就進入了下一次的迴圈。解決方案是使用 ‘/\A\d+\.?\d?/‘ 這個模式進行匹配。
#!/usr/bin/perl 2 use 5.010; 3 my $num; 4 while(chomp($num=<STDIN>)){ 5 next unless $num =~ /\A\d+\.?\d?\z/; #防止輸入的內容不是數字 6 given($num){ 7 when( not $_%3 ){ 8 print "Fizz "; 9 continue; 10 } 11 when( not $_%5 ){ 12 print "Bin "; 13 continue; 14 } 15 when( not $_%7 ){ 16 print "Sausage "; 17 continue; 18 } 19 default { print "\n";} 20 } 21 }
問題解決!
Perl學習筆記(2)----Regex數字匹配的一個疏忽