【问题标题】:Reliable Perl encoding with File::Slurp使用 File::Slurp 进行可靠的 Perl 编码
【发布时间】:2017-04-23 13:47:04
【问题描述】:

我需要用// 替换文件中每个出现的http://。该文件可能(至少)位于UTF-8CP1251CP1255

以下是否有效?

use File::Slurp;
my $Text = read_file($File, binmode=>':raw');
$Text =~ s{http://}{//}gi;
write_file($File, {atomic=>1, binmode=>':raw'}, $Text);

这似乎是正确的,但我需要确保文件不会被损坏,无论它有什么编码。请帮我确定一下。

【问题讨论】:

  • 我们好像没有 UTF-16 或 UTF-32 文件
  • 您的代码中有错字。它不会使用错误的模块名称进行编译。请解决这个问题。
  • 你事先知道每个文件的编码吗?
  • 我认为简单的perl -pi -e's{http://}{//}gi' 就足够了。
  • 我添加了 binmode=>':raw'。现在看来是正确的

标签: encoding perl slurp


【解决方案1】:

这个答案不能让你确定,但我希望它能有所帮助。

我看不出你的脚本有任何问题(用 utf8 ans iso-8859-1 测试没有问题)虽然似乎有关于 File::slurp 正确处理编码的能力的讨论:http://blogs.perl.org/users/leon_timmermans/2015/08/fileslurp-is-broken-and-wrong.html

在类似主题的这个答案中,由于更好的编码处理,作者推荐 File::Slurper 作为替代方案:https://stackoverflow.com/a/206682/6193608

【讨论】:

    【解决方案2】:

    不再推荐使用 File::Slurp (see here)。

    我建议使用Path::Tiny。它易于使用,适用于文件和目录,仅使用核心模块,并且具有专门用于 uft8 和 raw 的 slurp/spew 方法,因此您不应该对编码有任何问题。

    用法:

    use Path::Tiny;
    
    my $Text = path($File)->slurp_raw;
    
    $Text =~ s{http://}{//}gi;
    
    path($File)->spew_raw($Text);
    

    更新:来自关于 spew 的文档:

    以原子方式将数据写入文件。该文件被写入同一目录中的临时文件,然后在原始文件上重命名。可选的哈希引用可用于传递选项。唯一的选项是 binmode,它被传递给用于写入的句柄上的 binmode()。

    spew_raw 类似于 spew,其 binmode 为 :unix,用于快速、无缓冲的原始写入。

    spew_utf8 类似于 spew,binmode 为 :unix:encoding(UTF-8)(或 PerlIO::utf8_strict)。如果安装了 Unicode::UTF8 0.58+,将对使用 Unicode::UTF8 编码的数据进行原始喷射。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      相关资源
      最近更新 更多