使用 Perl 从字符串中删除 BOM

Posted

技术标签:

【中文标题】使用 Perl 从字符串中删除 BOM【英文标题】:Remove BOM from string with Perl 【发布时间】:2014-08-14 21:59:41 【问题描述】:

我有以下问题:我正在读取一个 UTF-8 文本文件(我通过 ":encoding(utf-8)" 告诉 Perl 我正在这样做)。

文件在十六进制查看器中如下所示: EF BB BF 43 6F 6E 66 65 72 65 6E 63 65

这在打印时转换为“∩╗┐Conference”。我了解我被警告的“宽字符”是 BOM。我想摆脱它(不是因为警告,而是因为它弄乱了我稍后进行的字符串比较)。

所以我尝试使用以下代码将其删除,但我失败了:

$line =~ s/^\xEF\xBB\xBF//;

谁能告诉我如何从我通过读取 UTF-8 文件的第一行获得的字符串中删除 UTF-8 BOM?

谢谢!

【问题讨论】:

只要正确设置了输出编码,就不需要删除 BOM,因为零宽度的空格对结果没有影响 【参考方案1】:

EF BB BF 是 BOM 的 UTF-8 编码,但是你解码了它,所以你必须寻找它的解码形式。 BOM 是在文件开头使用的零宽度无间断空格 (U+FEFF),因此可以执行以下任何操作:

s/^\xFEFF//;
s/^\NU+FEFF//;
s/^\NZERO WIDTH NO-BREAK SPACE//;
s/^\NBOM//;   # Convenient alias

我了解我被警告的“宽字符”是 BOM。我想摆脱它

因为忘记在输出文件句柄上添加:encoding 层,您的字符变宽了。下面将:encoding(UTF-8)添加到STDIN、STDOUT、STDERR,并使其成为open()的默认值。

use open ':std', ':encoding(UTF-8)';

【讨论】:

要使用简写,我需要添加 use charnames ':full'; 我认为\N... 需要5.12 我认为\NBOM 需要5.14。 5.16 之前需要use charnames ':full'; @user1769925:请注意,问题是您已经解码文件中的数据(因为您的:encoding(utf-8)打开模式)所以第一个字符 输入字符串是 Unicode U+FEFF,但您在替换中使用了原始 UTF-8 编码的数据字节 这些解决方案导致编译时错误,直到我添加以下代码:使用字符名“:完整”;。在那之后,解决方案仍然未能做出任何改变。最终为我解决了这个问题:使用编码;我的 $value = decode('UTF-8', $value); $value =~ s/\NU+FEFF//; @HoldOffHunger,已经提到在旧版本的 Perl 中需要use charnames ":full";。 /// 问题的关键部分是已经执行了 decode('UTF-8', $value) 的等价物——如果他们还没有解码文本,他们的代码本来可以工作的——所以在这里添加 decode('UTF-8', $value) 实际上是错误的。 【参考方案2】:

理想情况下,您的文件句柄应该会自动为您执行此操作。但是,如果您的情况不理想,这对我有用:

use Encode;

my $value = decode('UTF-8', $originalvalue);
$value =~ s/\NU+FEFF//;

【讨论】:

decode_utf8()快捷方式。【参考方案3】:

如果您使用File::BOM 打开文件,它将为您删除 BOM。

use File::BOM;

open_bom(my $fh, $path, ':utf8')

【讨论】:

【参考方案4】:

要化解 BOM,你必须知道它不是 3 个字符,而是 UTF (U+FEFF) 中的 1:

s/^\xFEFF//;

【讨论】:

乐于将它称为爆炸物。 正如@ikegami 所说,需要解码为UTF-8,即decode_utf8()

以上是关于使用 Perl 从字符串中删除 BOM的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 perl 从变量中删除特殊字符 [关闭]

从列表中的对象中删除字节顺序标记

从 Perl 中的字符串中删除文件扩展名和路径

在 Perl 中,如何从文件中删除 ^M?

如何删除从perl读取sql文件时附加的特殊字符

删除 perl 字符串中所有前导零的最优雅和最快的方法