2016-07-26 51 views
1

我有一個問題,我無法以適合於Stackoverflow的方式重現,儘管它在我的可重現生產環境。

問題occors在一個Perl腳本,除其他外,遍歷一個文件,看起來像這樣:

abc-4-9|free text, possibly containing non-ascii characters| 
cde-3-8|hällo wörld| 
# comment 

xyz-9-1|and so on| 
qrs-2-8|and so forth| 

我可以驗證這個Perl腳本文件的正確性:

use warnings; 
use strict; 

open (my $f, '<:encoding(UTF-8)', 'c:\path\to\file') or die "$!"; 

while (my $s = <$f>) { 
    chomp($s); 
    next unless $s; 
    next if $s =~ m/^#/; 
    $s =~ m!(\w+)-(\d+)-(\d+)\|([^|]*)\|! or die "\n>$s<\n didn't match on line $."; 
} 

print "Ok\n"; 
close $f; 

當我運行這個腳本時,它不會死於第10行,因此打印Ok

現在,我在一個巨大的Perl腳本中使用基本相同的構造(因此對於Stackoverflow而言是不可再生的),它將死於輸入文件的第2199行。

如果我改變的東西,從第一行(這是完全無關的行2199)像

www-1-1|A line with some words| 

www-1-1|x| 

腳本將處理線2199(但是後來失敗)。

有趣的是,當我改變

open (my $f, '<', 'c:\path\to\file') or die "$!"; 

open (my $f, '<:encoding(UTF-8)', 'c:\path\to\file') or die "$!"; 

沒有:encoding(UTF-8)指令,此行爲已出臺,該腳本不會失敗。當然,我需要編碼指令,因爲該文件包含非ASCII字符。

順便說一句,同樣的腳本在Linux上運行沒有問題。

在Windows上,它失敗了,我用草莓的Perl 5.24

+0

該文件沒有BOM。由於它包含機密數據,所以我不能不幸的只是複製並粘貼前幾行。 –

+1

添加'使用Devel :: Peek;'並用'Dump($ s)替換'die ...',死...'。請提供輸出。 – ikegami

+0

或者,用'do {use Data :: Dumper; local $ Data :: Dumper :: Useqq = 1; die Dumper($ s)'替換'die ...''。 「。(utf8 :: is_utf8($ s)?1:0)。」在$行。不匹配「};' – ikegami

回答

2

我沒有爲什麼,這是必要的充分和正確的解釋,但你可以嘗試打開文件

'<:unix:encoding(UTF-8)' 

這可能與我的問題「Why is CRLF set for the unix layer on Windows?」有關,當我試圖找出那些我從未想到的東西時,我注意到了它。