0

私は今、エンコーディングスキームに夢中です。私の問題を以下に述べます、あなたのインプットを与えてください。

問題:以下のコードに記載されている入力文字列があります。最終的に必要な出力は「Křižovnická190」です。[ここでデコードできます]。私はこれらの種類の文字列をデコードするためにperlモジュールを使用しています。以下は私のテストコードです:

use HTML::Entities;
binmode STDOUT,":utf8";
$a = "Křižovnická 190";
decode_entities($a);
print $a."\n";

ただし、出力は「Křiovnická19」です。これは、「ř」が正しくデコードされていることを意味しますが、「ž」は正しくデコードされていません。私の質問はなぜですか?次に、entity2charハッシュを提供する「_decode_entities」メソッドを試しましたが、それでも成功しませんでした。

PS:他のレガシーAPIがあるため、ここではPerlを使用する必要があります。ここで私を助けてください

4

2 に答える 2

7

文字「ž」はž、Unicodeではに対応しžます。158は、cp1252の「ž」のエンコーディングです。

ところで、Clementinumはいいです。

明確にするために:

| Grapheme   |         ř         |         ž         |
|------------+-------------------+-------------------|
| Codepoint  | U+0159 (345)      | U+017E (382)      |
| Escape     | ř (ř) | ž (ž) |
|------------+-------------------+-------------------|
| UTF-8      | C5 99 (197 153)   | C5 BE (197 190)   | 
| cp1252     | -                 | 9E    (158)       |
| latin2     | F8    (248)       | BE    (190)       |

アップデート:

詳細については、ウィキペディアのHTML10進文字レンダリングを参照してください。重要な部分は次のとおりです。

(...)文字128〜159への参照は、一般に、寛大なWebブラウザーによって、Windows-1252文字エンコードのバイト128〜159(10進数)に割り当てられた文字への参照であるかのように解釈されます。これはHTMLおよびSGML標準に違反しており、文字はすでに上位のコードポイントに割り当てられているため、HTMLドキュメントの作成者は常に上位のコードポイントを使用する必要があります。たとえば、商標記号(™)には™、ではなくを使用します™

于 2012-10-15T14:04:19.873 に答える
2

ž「ž」は参照しません。それはU+009E PRIVACY MESSAGE、制御文字です。(158 10 = 9E 16

「ž」はU+017E LATIN SMALL LETTER Z WITH CARONなので、エスケープはžまたはになりžます。

一部のWebブラウザーは、値が80..9F 16(128..159 10)の数値エンティティを誤って解釈し、その数値をUnicodeコードポイントのWindows-1252エンコーディングとして扱います。

| Grapheme           |         ř         |         ž         |
+--------------------+-------------------+-------------------+
| Unicode Code Point | U+0159 (345)      | U+017E (382)      |
| Escape             | ř (ř) | ž (ž) |
+--------------------+-------------------+-------------------+
| cp1252 encoding    | ---               | 9E (158)          |
| Alternate escape*  | ---               | ž (ž)   |

* — Non-standard and buggy behaviour.

このバグのある動作は、あなたが望むものです。その動作を実装するモジュールが表示されないため、独自にコーディングする必要があります。

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

use HTML::Entities qw( );
use Encode         qw( decode );

{
    my %fixes =
        map { chr($_) => decode('cp1252', chr($_)) }
          0x80..0x9F;

    sub decode_entities {
        my $s_ref = defined(wantarray())
            ? do { my ($s) = @_; \$s }
            : \$_[0];

        $$s_ref =~ s{(
            &\#
            (?: 0*([1-9][0-9]*);?
            |   x0*([1-9A-Fa-f][0-9A-Fa-f]*);?
            )
        )}{
            if (defined($2) && length($2) == 3 && exists($fixes{chr($2)})) {
               $fixes{chr($2)}
            } elsif (defined($3) && length($3) == 2 && exists($fixes{chr(hex($3))})) {
               $fixes{chr(hex($3))}
            } else {
               $1
            }
        }exg;

        HTML::Entities::decode_entities($$s_ref);
        return $$s_ref;        
    }
}

print(decode_entities("Křižovnická 190"), "\n");
于 2012-10-15T17:08:26.227 に答える