使用 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的主要内容,如果未能解决你的问题,请参考以下文章