4

このDate::Holidays::DKモジュールでは、特定のデンマークの祝日の名前が Latin1 エンコーディングで記​​述されています。たとえば、1 月 1 日は「Nytårsdag」です。$x適切な utf8 でエンコードされた文字列を取得するには、以下をどうすればよいですか?

use Date::Holidays::DK;
my $x = is_dk_holiday(2011,1,1);

use utf8no utf8before/afterの組み合わせをいろいろ試してみuse Date::Holidays::DKましたが、効果がないようです。Encode の も使用しようとdecodeしましたが、うまくいきませんでした。すなわち、

use Date::Holidays::DK;
use Encode;
use Devel::Peek;
my $x = decode("iso-8859-1", 
           is_dk_holiday(2011,1,1)
          );
Dump($x);
print "January 1st is '$x'\n";

出力を与える

SV = PV(0x15eabe8) at 0x1492a10
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK,UTF8)
  PV = 0x1593710 "Nyt\303\245rsdag"\0 [UTF8 "Nyt\x{e5}rsdag"]
  CUR = 10
  LEN = 16
January 1st is 'Nyt sdag'

(t と s の間に無効な文字があります)。

4

2 に答える 2

4

Date::Holidays::DK を使用する前後に utf8 を使用し、utf8 を使用しないようにしますが、効果はないようです。

正しい。utf8プラグマは、プログラムのソース コードが UTF-8 で記述されていることのみを示します

また、Encode のデコードを使用しようとしましたが、うまくいきませんでした。

あなたはこれを正しく認識していませんでした。実際、あなたは正しいことをしました。これで、Perl 文字のストリングができて、それを操作できるようになりました。

t と s の間に無効な文字がある

あなたもこれを間違って解釈しますが、それは実際にはåキャラクターです。


UTF-8 を出力したいので、エンコード手順が不足しています。

my $octets = encode 'UTF-8', $x;
print $octets;

エンコーディングのトピックの紹介については、http://p3rl.org/UNIを参照してください。明示的または暗黙的に、常にデコードおよびエンコードする必要があります。

于 2011-07-14T15:03:17.900 に答える
2

use utf8ファイルが UTF-8 でエンコードされているという perl インタープリター/コンパイラーへのヒントのみです。上位ビットが設定された文字列がある場合、それらは自動的に Unicode にエンコードされます。

iso-8859-1 でエンコードされた変数がある場合は、それをデコードする必要があります。次に、変数は内部ユニコード形式です。これは utf8 ですが、perl が内部的にどのエンコーディングを使用しているか気にする必要はありません。

このような文字列を出力したい場合は、Unicode 文字列をバイト文字列に戻す必要があります。この文字列に対して a を実行する必要がありencodeます。手動でエンコードを行わない場合、perlそれ自体が iso-8859-1 にエンコードされます。これがデフォルトのエンコーディングです。

変数 $x を印刷する前に、それに対して a を実行する必要があります$x = encode('UTF-8', $x)

UTF-8 を正しく処理するには、I/O を介したすべての外部入力を常に decode() する必要があります。そして、プログラムから出るすべてのものを常に encode() する必要があります。

デフォルトの入出力エンコーディングを変更するには、次のようなものを使用できます。

use utf8;
use open ':encoding(UTF-8)';
use open ':std';

最初の行は、ソース コードが utf8 でエンコードされていることを示しています。2 行目は、すべての入力/出力が自動的に utf8 でエンコードされる必要があることを示しています。open()utf8 モードでもファイルを開くことに注意することが重要です。バイナリ ファイルを扱う場合はbinmode()、ハンドルで a を呼び出す必要があります。

ただし、2 行目は、STDIN、STDOUT、または STDERR の処理を​​変更しません。3 行目はそれを変更します。

おそらく、このプロセスを簡単にするモジュールutf8:allを使用できます。しかし、これらすべてが舞台裏でどのように機能するかを理解することは常に良いことです。

あなたの例を修正するには。考えられる方法の1つは次のとおりです。

#!/usr/bin/env perl
use Date::Holidays::DK;
use Encode;
use Devel::Peek;
my $x = decode("iso-8859-1", 
           is_dk_holiday(2011,1,1)
          );
Dump($x);
print encode("UTF-8", "January 1st is '$x'\n");
于 2011-07-14T14:57:02.097 に答える