html - 字符编码搞乱了 Perl 正则表达式

标签 html perl utf-8 character-encoding utf

简短版本:这是一个最小的失败示例:

$> echo xóx > /tmp/input
$> hex /tmp/input
0x00000000: 78 c3 b3 78 0a
$> perl -e 'open F, "<", "/tmp/input" or die $!;
       while(<F>) {
           if ($_=~/x(\w)x/) {
               print "Match:$1\n";
           }else{
               print "No match\n";
           }
       }'
No match

为什么会失败以及如何使 Perl 脚本接受 ó with \w


长版本:我正在使用 Perl (5.10) 从 HTML 中抓取数据。 最终目标是让字符串仅由 ASCII 可打印集 (0x20-0x7F) 表示。这将涉及更改,例如ó 至 ó还可以将某些字符映射到近似值,例如各种空间最终为 0x20某种撇号(见下文)最终应该是普通的旧 0x27 .

当“ó”=~/\W/返回 true 时,我的任务开始了,这让我感到惊讶,因为 perldoc perlretut告诉我

\w matches a word character (alphanumeric or _), not just [0-9a-zA-Z_] but also digits and characters from non-roman scripts

我认为这与字符编码有关。我对此了解不多,但源 HTML 包含

<meta http-equiv="Content-type" content="text/html; charset=utf-8" />

十六进制转储告诉我 ó 被编码为 b3c3而不是f3正如我最初预期的那样。

在 Perl 中,我尝试使用 open F, "<:encoding(UTF-8)", $f 修复此问题但这给了我错误,例如

utf8 "\xF3" does not map to Unicode

和字符串如 \xF3出现在 read 的输出中。当我注意到一些字符的编码是无序的,我根本不理解时,情况变得更奇怪了。以下是两个十六进制转储(UNIX hexdump 实用程序)用于比较:

拉尔特 => 61 52 74 6c

Réalt => c3 52 61 a9 74 6c

什么鬼?

此外,这是我之前提到的那个该死的撇号。

拍=> 61 50 73 74

帕特 => 61 50 e2 74 99 80

这是我的问题:

  1. 疯狂的乱序编码是怎么回事?
  2. 我可以配置 Perl 以接受正则表达式中的上述字符串,例如 s/ó/ó/g 吗?
  3. 我可以做些什么来改变例如Pat's 变成 Pat's 并基本上将其全部转换为 ASCII,并使用 HTML 实体表示通常的重音元音?

对于第 2 部分,我可以确认我的键盘使用与读入的文件相同的编码将 ó 输入到文本编辑器中。

对于第 3 部分,完全没有必要留在 Perl 中。我也只需要常见标点符号(如撇号)的映射。任何没有明显 ASCII 等效项的外来字符都是意外的,应该简单地触发失败。

最佳答案

  1. 你的 hexdumper 很糟糕。使用合适的。

    $ echo -n Réalt | hex
    0000  52 c3 a9 61 6c 74                                 R..alt
    $ echo -n Pat’s | hex
    0000  50 61 74 e2 80 99 73                              Pat...s
    
  2. 是的,配置是use utf8;,这样Perl源代码中的文字ó就会被视为一个字符。 s/ó/ó/g 工作得很好,但您应该使用模块来处理实体,如下所示。

3.

    use utf8;
    use HTML::Entities qw(encode_entities);

    encode_entities 'Réalt';    # returns 'R&eacute;alt'
    encode_entities 'Pat’s';    # returns 'Pat&rsquo;s'

阅读http://p3rl.org/UNI了解 Perl 中的编码主题。

关于html - 字符编码搞乱了 Perl 正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9296061/

相关文章:

html - 在表单搜索中结合 input-prepend 和 input-append

html - 在 div 的底部居中图像,上面有视口(viewport)高度

html - 为什么过渡不起作用?

regex - 正则表达式从末尾解析字符串直到到达分隔符(Perl)

Perl 以最有效的方式在重复模式上拆分字符串?

perl - 如何整理 DBIx::Class::Schema::Loader 的输出?

python - 什么可能导致此错误: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 568: invalid start byte

Java判断字符串中的字符是否在给定范围内

php - 在 Eclipse 中编码

javascript - 如何为用户提供html/js widget