【问题标题】:Encode module and inverted commas编码模块和引号
【发布时间】:2016-10-11 20:51:20
【问题描述】:

我正在抓取网页,并从中提取特定部分。该部分包括引号(,字符 146)。我正在尝试将提取的数据打印到文本文件中,但它给了我’ 而不是引号。我尝试了以下方法:

  • $content =~ s/’/'/g;
  • my $invComma = chr 146; $content =~ s/$invComma/'/g;
  • $content =~ s/\x{0092}/'/g;

这些都没有奏效。我不能decode('UTF-8', $content) 因为它有宽字符。当我尝试 encode('UTF-8', $content) 时,’ 改为 ’。我也试过use utf8,没有效果。

我知道我的文本文件查看器可以显示逗号,因为我将一个逗号打印到一个测试文件并打开它。因此问题出在我的脚本中。

我做错了什么,我该如何解决?

更新:我可以使用$content =~ s/’/'/g 将其替换为一个简单的撇号,但我仍然不知道为什么其他方法都不起作用。我还想要一个真正解决问题的修复程序,而不仅仅是解决其中一个症状。

更新 2hobbs 告知我该字符实际上是 U+2019 RIGHT SINGLE QUOTATION MARK,并将我的正则表达式更改为使用 chr 0x2019,现在可以使用了。

【问题讨论】:

  • 无论您获取网页的内容如何,​​它都误解了编码 - 但您没有在问题中包含这部分代码。
  • 我正在使用 LWP::Simple 的 get(URL) 方法。你会推荐什么?
  • 你确定 反逗号 是 146 吗?我只是将它从您的 OP 复制并粘贴到我的编辑器中,保存它,执行hexdump -C 并得到e2 80 99
  • @PerlDog 你是对的,我什至没有注意到。
  • 这个字符: 是右单引号,Unicode 0x2019。我见过术语“反逗号”用于指代某种引号,但它似乎并不常见(也许它是英国特有的?)。 Unicode 没有定义“倒置逗号”字符。并且 chr(146) 是 Unicode 中的控制字符(“PRIVATE USE TWO”)——尽管它是 Windows-1252 中的右单引号。

标签: perl encoding utf-8


【解决方案1】:

您尝试替换的字符在 Windows-1252 编码中仅为 0x92 / 146。 Perl 使用 Unicode,其中该字符是 U+2019 RIGHT SINGLE QUOTATION MARK、又名 "\x{2019}"chr(0x2019)chr(8217)

【讨论】:

  • 所以我应该在网上寻找合适的 unicode 代码点并以这种方式进行替换?我可以在我的输入上使用编码模块吗?如果有,怎么做?
  • @Lilith 你不需要 Encode 模块,你的输入已经被 LWP 正确解码(使用 Encode 模块)。 LWP::Simple 使用 HTTP::Response 的 decoded_content 方法。
  • 那么如何让我的脚本正确打印呢?我使用 IO::All 将输出文件标记为 utf8,然后直接打印输出。它改为显示为“’”。我可以只添加三个字符的替换(打开/关闭双引号和右单引号),但我宁愿解决问题而不是症状。
  • @Lilith 出现在什么地方?您是否以不支持 unicode 的方式打开输出文件?或者你正在做其他事情来欺骗编码检测?这真的很难说,除了问题不在你认为的地方。
  • 我在 Windows 上使用 gVim,你认为是这样吗?
【解决方案2】:

首先找出$content 包含的内容。您可以使用以下内容:

use Data::Dumper;
local $Data::Dumper::Useqq = 1;
warn(Dumper($content));

如果你得到以下,$content 被解码

$VAR1 = "...\x{2019}...";

以下任何一种都可以。

use utf8;  # Source code is encoded using UTF-8.
$content =~ s/’/'/g;

$content =~ s/\x{2019}/'/g;

$content =~ s/\N{U+2019}/'/g;

$content =~ s/\N{RIGHT SINGLE QUOTATION MARK}/'/g;

如果您得到以下信息,$content 使用 UTF-8 编码。

$VAR1 = "...\342\200\231...";

首先使用以下任一方法解码$content 的值:

utf8::decode($content) or die;

use Encode qw( decode_utf8 );
$content = decode_utf8($content);

然后对解码的内容使用任何解决方案(上图)。


如果您得到以下信息,$content 将使用 cp1252 进行编码。

$VAR1 = "...\222...";

首先解码$content的值。

use Encode qw( decode );
$content = decode("cp1252", $content);

然后对解码的内容使用任何解决方案(上图)。


顺便说一句,’ (E2 80 99) 的 UTF-8 编码如果解码为 cp1252 的样子。

【讨论】:

    【解决方案3】:

    问题不在于我的脚本,而在于我的编辑器。该脚本工作正常,问题是基于虚假的借口。我在 Windows 上使用 gVim,它不能很好地与 Unicode 配合使用。我的脚本正确解码了内容,但是当我在 gVim 中打开输出文件时,它破坏了文本并错误地显示它。我使用正则表达式更改字符的尝试失败了,因为我使用了错误的代码点——不是 0x92,而是 0x2019。这是 gVim 的另一个失败。感谢 hobbsikegami 帮助我解决这个问题。

    【讨论】:

      猜你喜欢
      • 2015-07-29
      • 2011-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多