【问题标题】:Malformed UTF-8 character when matching Non Breaking Space匹配非中断空格时出现格式错误的 UTF-8 字符
【发布时间】:2019-01-31 01:44:12
【问题描述】:

我在我的 perl 程序中使用 utf8,我有以下代码行:

$$pstring =~ s/\xA0/ /g; 

应该从字符串中清除非中断空格。

在 Ubuntu 16.04 和 perl v5.22.1 下这不是问题,但在 Ubuntu 14.04 和 v5.18.2 下我收到此错误:

格式错误的 UTF-8 字符(致命)

然后我检查了我试图匹配的字符串,发现里面有不间断的空格,可以被正则表达式删除

$$pstring =~ s/[\xC2\xA0]/ /g;

但没有

$$pstring =~ s/\xC2\xA0/ /g;

我的问题是:最后两者有什么区别(为什么它只适用于括号),还有其他方法可以解决这个问题吗?

【问题讨论】:

  • use diagnostics
  • Re "$$pstring",你为什么要引用一个标量?这可能是合法的,但很奇怪
  • 实际上我的字符串中有两个后续的 \xA0 字符.. $$pstring =~ s/\xA0+/ /g;修好了。

标签: regex perl utf-8


【解决方案1】:

我的猜测是您正在处理原始的 UTF-8 编码字符串。你没有展示你是如何得到它的,也没有说明你为什么要这样做。一个小而完整的演示程序展示了您如何获得输入、如何更改输入以及最终抱怨的内容,这将帮助人们找到问题所在。如果您将那个小型演示程序添加到您的问题中,我可能会给出更好(甚至不同)的答案。

不间断空格的代码编号为 U+00A0。在 UTF-8 下,它编码为两个八位字节 \xC2 和 \xA0。代码编号高于 U+007F 的所有内容都具有 UTF-8 下的多字节编码。 U+007F 下的所有内容实际上都只是 ASCII,因此 ASCII 作为 UTF-8 工作。

如果您有带有不间断空格的 UTF-8 编码文本并仅删除 \xA0 八位字节,则剩下一个孤独的 \xC2。根据之后发生的情况,这可能是一个问题。 UTF-8 旨在识别问题所在并自行纠正。它可以拾取下一个合法编码的字符并留下一个替换字符来标记错误。或者,程序可以抱怨并放弃。

当您使用字符类[\xC2\xA0] 时,我猜它会在它们出现的任何地方摆脱这些八位字节中的任何一个。由于您没有报告任何其他错误,我猜\xC2 不会出现在其他任何地方。否则,其他字符可能会改变。或者,您正在处理扩展的 ASCII 并删除 \xC2 留下正确的 Latin-1 编码。 s/// 报告的替换数量是否等于不间断空格的数量(或两倍)?

如果您有 UTF-8 编码的文本,请将其读取为 UTF-8:

open my $fh, '<:utf8', $filename or die ...

读取数据后,不必担心编码问题。使用代码编号,Perl 会弄清楚。或者使用代码名称,以便未来的程序员无需查找字符即可知道您在做什么:

my $string =~ s/\x{00A0}/ /g;
my $string =~ s/\N{NO-BREAK SPACE}/ /g;

完成后,将其写为 UTF-8 文本:

open my $fh, '>:utf8', $filename or die ...

最新的Learning Perl 在后面有一个 Unicode 入门,涵盖了相当多的内容。

祝你好运!

【讨论】:

  • 很好的描述性答案,一如既往
猜你喜欢
  • 2016-11-13
  • 2013-08-06
  • 2019-04-05
  • 1970-01-01
  • 2014-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多