Perl - 使用 .html 文件时出现编码错误

Perl - Encoding error when working with .html file

我的目录中有一些 .html 文件,我想向其中添加一行 css 代码。使用 perl,我可以使用正则表达式定位位置并添加 css 代码,这非常有效。

但是,我的第一个 .html 文件包含一个重音字母:é 但生成的 .html 文件存在编码问题并打印:\xE9

在perl文件中,我已经在打开和关闭文件时小心地指定了UTF-8编码,在下面的MWE中显​​示,但并没有解决问题。我该如何解决这个编码错误?

MWE

use strict;
use warnings;
use File::Spec::Functions qw/ splitdir rel2abs /; # To get the current directory name

# Define variables
my ($inputfile, $outputfile, $dir);

# Initialize variables
$dir = '.';

# Open current directory
opendir(DIR, $dir);

# Scan all files in directory
while (my $inputfile = readdir(DIR)) {
    
    #Name output file based on input file
    $outputfile = $inputfile;
    $outputfile =~ s/_not_centered//;
    
    # Open output file
    open(my $ofh, '>:encoding(UTF-8)', $outputfile);

    # Open only files containning ending in _not_centered.html
    next unless (-f "$dir/$inputfile");
    next unless ($inputfile =~ m/\_not_centered.html$/);
    
    # Open input file
    open(my $ifh, '<:encoding(UTF-8)', $inputfile);
    
    # Read input file
    while(<$ifh>) {
        # Catch and store the number of the chapter
        if(/(<h2)(.*?)/) {
            # $_ =~ s/<h2/<h2 style="text-align: center;"/;
            print $ofh " style=\"text-align: center;\"";
        }else{
            print $ofh "$_";
        }
    }
    
    # Close input and output files
    close $ifh;
    close $ofh;
}

# Close output file and directory
closedir(DIR);

名为“Chapter_001_not_centered.html”的有问题文件

<html > 
<head></head>
<body>
                                                           
<h2 class="chapterHead"><span class="titlemark">Chapter&#x00A0;1</span><br /><a id="x1-10001"></a>Brocéliande</h2>
Brocéliande

</body></html>

以下演示脚本确实需要 注入 并利用 glob 函数。

注意:脚本会创建一个新文件,取消注释重命名以用新文件替换原始文件

use strict;
use warnings;

use open ":encoding(Latin1)";

my $dir = '.';

process($_) for glob("$dir/*_not_centered.html");

sub process {
    my $fname_in  = shift;
    my $fname_new = $fname_in . '.new';
    
    open my $in, '<', $fname_in
        or die "Couldn't open $fname_in";
        
    open my $out, '>', $fname_new
        or die "Couldn't open $fname_new";
        
    while( <$in> ) {
        s/<h2/<h2 style="text-align: center;"/;
        print $out $_;
    }
    
    close $in;
    close $out;

    # rename $fname_new, $fname_in
    #    or die "Couldn't rename $fname_new to $fname_in";

}

如果您不介意 运行 根据每个单独的文件执行以下脚本 script.pl in_file > out_file

use strict;
use warnings;

print s/<h2/<h2 style="text-align: center;"/ ? $_ : $_ for <>;

如果这样的任务只是偶尔出现,那么用一个 liner 就可以解决

perl -pe "s/<h2/<h2 style='text-align: center;'/" in_file

这个问题在@Shawn 和@sticky bit 的评论中找到了答案:

通过将打开和关闭文件的编码更改为 ISO 8859-1,它解决了问题。如果你们中有人想要 post 答案,我会验证它。