2

値が一連のバイトまたはエンコードされた文字列であるかどうかを判断するPerlの標準テストは何ですか? また、それがエンコードされた文字列である場合、それはどの文字エンコードですか?

次の完全な Perl スクリプトがあるとします。

'foo';

このリテラル文字列が一連のバイトなのか、エンコーディングの文字列なのかをどのように判断しますか? また、ある文字エンコーディングの文字列である場合、それはどの文字エンコーディングですか?

この質問は、Unicode や UTF-8 に関するものではありません。これは、一般的に Perl のバイト対文字に関するものです。この質問は、完全に別のトピックである自動文字エンコーディング検出に関するものでもありません。

アップデート

を初期化した後$letter、変数に格納されている文字がどの文字エンコーディングであると Perl が判断したかを Perl に教えてもらいたいのですが、それが必ずしも正しい$letterとは思いません。文字がどの文字エンコーディングに含まれているかを Perl が確実に理解できるようにするのは、プログラマーとしての私の責任です。わかりました。しかし、Perl が文字 (または文字列) を認識している文字エンコーディングをテストする単純で簡単な方法があるはずです。ありませんか?

C:\>perl -E "$letter = 'Ž'; say $letter =~ m/\w/ ? 'matches' : 'does not match'"
does not match

C:\>perl -MEncode -E "$letter = decode('UTF-8', 'Ž'); say $letter =~ m/\w/ ? 'matches' : 'does not match'"
does not match

C:\>perl -MEncode -E "$letter = decode('Windows-1252', 'Ž'); say $letter =~ m/\w/ ? 'matches' : 'does not match'"
matches

C:\>perl -MEncode -E "$letter = decode('Windows-1252', 'Ž'); $letter = encode('Windows-1252', $letter); say $letter =~ m/\w/ ? 'matches' : 'does not match'"
does not match

C:\>chcp
Active code page: 1252

C:\>

Perlは、格納された値が (正しいか間違っているかに関わらず)理解$letterしている文字エンコーディングをオンデマンドで報告できませんか?

4

5 に答える 5

0

cp1252 の "Ž" は 8E ですので、 として認識されるもの'Ž'は と同じchr(0x8E)です。

それと次のことを念頭に置いて、

decode('UTF-8', chr(0x8E))     ===   chr(0xFFFD)  [Invalid UTF-8]
decode('cp1252', chr(0x8E))    ===   chr(0x17D)
encode('cp1252', chr(0x17D))   ===   chr(0x8E)
  1. 最初のスニペットは、0x8E を一致演算子に渡します。U+008E (SINGLE SHIFT TWO) は「単語」コード ポイントではありません。

    表示されているのは、Unicode コード ポイント (cp1252 でエンコードされたテキスト) 以外のものを、Unicode コード ポイントを期待するオペレーターに渡すことの影響です。

  2. 2 番目のスニペットは、0xFFFD を一致演算子に渡します。U+FFFD (置換文字) は「単語」コード ポイントではありません。

    あなたが見ているのは、UTF-8 でエンコードされたテキスト (cp1252 でエンコードされたテキスト) 以外のものを UTF-8 を期待する関数に渡すことの効果です。

  3. 3 番目のスニペットは、0x017D を一致演算子に渡します。U+017D (LATIN CAPITAL LETTER Z WITH CARON) は「単語」コードポイントです。

  4. 4 番目のスニペットは、最初のスニペットと同様に、0x8E を一致演算子に渡します。

    表示されているのは、Unicode コード ポイント (cp1252 でエンコードされたテキスト) 以外のものを、Unicode コード ポイントを期待するオペレーターに渡すことの影響です。

あなたの更新は、以前の回答がすでにあなたに伝えたことを実際に示しています。一致演算子は常に文字列をコードポイントの文字列と見なします。動作は常に同じであるため、確認する必要はありません。

(「セマンティクス」に関する一節は、更新とは関係ありません。正しい動作は常に得られ-Eます。)

于 2013-07-08T04:54:07.403 に答える
-2

Perl には、文字列がどの文字エンコーディングであると推定されるかを知る簡単な方法がありません。Perl には、文字列の内部表現が UTF-8 であるかどうかを判断するために調べることができる内部フラグがありますが、これはまったく異なります。文字列の文字エンコーディングを決定するためのテストではありません。

encoding() という名前の概念的な組み込み関数を想像してみましょう。これが何をするかは次のとおりです。

C:\>perl -E "say encoding 'quick brown fox'"
ISO-8859-1

C:\>perl -E "use utf8; say encoding 'quick brown fox'"
UTF-8

C:\>perl -E "use utf8; say encoding 'γρήγορη καφέ αλεπού'"
UTF-8

C:\>perl -Mutf8 -MEncode -E "say encoding decode('ISO-8859-7', 'γρήγορη καφέ αλεπού')"
ISO-8859-7

C:\>

(デフォルトの文字エンコーディングは ISO-8859-1 で、Latin 1 とも呼ばれます。)

これは、他の人が考えているほど難しい質問と回答ではありません。これがまさにそのポイントです。Perlに、文字列に割り当てられた文字エンコーディングを報告する組み込み関数があれば、さまざまな文字エンコーディングの理解、議論、対処がずっと簡単になります。

于 2013-07-08T05:00:40.200 に答える