10

誰かが私に RTFM を教えてくれる前に、私は言わなければなりません - 私は掘り下げました:

したがって、基本的なコードは次のとおりです。

use 5.014;           #getting 'unicode_strings' feature
use uni::perl;       #turning on many utf8 things
use Unicode::Normalize  qw(NFD NFC);
use warnings;
while(<>) {
    chomp;
    my $data = NFD($_);
    say "OK" if utf8::is_utf8($data);
}

この時点で、utf8でエンコードされた STDIN から正しい Unicode 文字列を取得しまし。たとえば、"\w" はマルチバイト(おそらくそれ以上) に一致します。それは大丈夫です。$data[\p{Alphabetic}\p{Decimal_Number}\p{Letter_Number}]

AFAIKにはutf8は含まれ$dataていませperl's internal Unicodeが、フォーマットされた文字列です。

今質問:

  • $other_data有効な Unicode 文字列が含まれていることを確認 (テスト) するにはどうすればよいですか?
  • utf8::is_utf8($data) の目的は何ですか? utf8プラグマ全体が私にとって謎です。

これは、私のソース コードが utf8 であることを Perl に伝える目的のみであることを理解していuse utf8;ます (つまり、私のスクリプトが BOM フラグで始まる場合と同様のことを行います - BigEndian の場合) - Perl の観点からは、私のソース コードは外部のようなものですfile - Perl はそれがどのエンコーディングであるかを知る必要があります...

上記の例でutf8::is_utf8($data)は OK と出力されますが、理由がわかりません。

内部的に Perl は utf8 を使用しないため、私の utf8 データ ファイルは Perl の内部 Unicode に変換さutf8::is_utf8($data)ます。または、名前が間違っていて、関数の名前を uni::is_unicode($data) にする必要があります???$data

明確にしていただきありがとうございます。

Ps: @brian d foy - はい、私はまだEffective Perl Programmingの本を持っていません- 私はそれを手に入れます - 私は約束します:) /冗談/

4

2 に答える 2

7

is_utf8使用された内部ストレージ形式、期間に関する情報を返します。

  • 文字列の値とは関係ありません (ただし、特定の文字列は 2 つの形式のいずれかでしか格納できません)。
  • 文字列がデコードされているかどうかには関係ありません。
  • 文字列に UTF-8 でエンコードされたものが含まれているかどうかは関係ありません。
  • これは、いかなる種類の有効性チェックでもありません。

それでは、質問に移りましょう。


utf8 プラグマ全体が私にとって謎です。

use utf8;perlソース コードが UTF-8 を使用してエンコードされていることを示します。そう言わないと、perl実質的にそれが iso-8859-1 であると想定されます (内部メカニズムの副作用として)。

utf8:: 名前空間の関数はプラグマとは関係なく、さまざまな目的に使用されます。

  • utf8::encodeおよびutf8::decode: 便利なエンコードおよびデコード機能。encode_utf8Encode のとに似ていますdecode_utf8が、インプレースで動作します。
  • utf8::upgradeand utf8::downgrade: ほとんど使用されませんが、XS モジュールのバグを回避するのに役立ちます。これについては、以下で詳しく説明します。
  • utf8::is_utf8: なぜ誰かがそれを使用するのかわかりません。

$other_data に有効な Unicode 文字列が含まれていることをどのように確認 (テスト) できますか?

あなたにとって「有効な Unicode 文字列」とは何を意味しますか? Unicode には、さまざまな状況で有効なさまざまな定義があります。


utf8::is_utf8($data) の目的は何ですか?

デバッグ。Perlの根性をのぞきます。


上記の例では、utf8::is_utf8($data) は OK を出力しますが、理由がわかりません。

NFD はたまたま UTF8=1 形式の文字列を含むスカラーを返すことを選択したためです。

Perl には、文字列を格納するための 2 つの形式があります。

  • UTF8=0 は、一連の 8 ビット値を格納できます。
  • UTF8=1 は、72 ビット値のシーケンスを格納できます (ただし、実際には 32 ビットまたは 64 ビットに制限されます)。

最初の形式は、メモリの使用量が少なく、文字列内の特定の位置にアクセスする場合は高速ですが、格納できる内容が制限されます。(たとえば、21 ビットが必要なため、Unicode コード ポイントを格納することはできません。) Perl は 2 つの間を自由に切り替えることができます。

use utf8;
use feature qw( say );

my $d = my $u = "abcdé";
utf8::downgrade($d);  # Switch to using the UTF8=0 format for $d.
utf8::upgrade($u);    # Switch to using the UTF8=1 format for $u.

say utf8::is_utf8($d) ?1:0;   # 0
say utf8::is_utf8($u) ?1:0;   # 1
say $d eq $u          ?1:0;   # 1

通常はこれについて心配する必要はありませんが、バグのあるモジュールがあります。にもかかわらず、Perl のバグのあるコーナーさえ残っていuse feature qw( unicode_strings );ます。utf8::upgradeandを使用しutf8::downgradeて、スカラーの形式を XS 関数で期待される形式に変更できます。


または、名前が間違っていて、関数の名前を uni::is_unicode($data) にする必要があります???

それは良くありません。Perl には、文字列が Unicode 文字列かどうかを知る方法がありません。それを追跡する必要がある場合は、自分で追跡する必要があります。

UTF8=0 形式の文字列には、Unicode コード ポイントが含まれる場合があります。

my $s = "abc";  # U+0041,0042,0043

UTF8=1 形式の文字列には、Unicode コード ポイントではない値が含まれる場合があります。

my $s = pack('W*', @temperature_measurements);
于 2012-05-30T21:28:27.900 に答える
6

$other_data に有効な Unicode 文字列が含まれていることをどのように確認 (テスト) できますか?

文字列に文字セマンティクスまたはバイト セマンティクスがあるかどうかを事後的に判断することはできません。Perl はこれを追跡しません。注意深いプログラミングによって追跡する必要があります。境界でエンコードおよびデコードします。バイトセマンティクス、文字セマンティクスの:raw レイヤー:encoding(foo)変数と関数に命名規則を採用して、セマンティクスを明確に区別し、間違ったコードが間違っているように見えるようにします。

utf8::is_utf8($data) の目的は何ですか?

SvUTF8フラグの存在を示すだけで、それ以上のことはありません。これは内部の問題であるため、ほとんどの開発者にとってはほとんど役に立ちません。このフラグは、文字列に文字セマンティクスがあることを意味しません。フラグがないからといって、文字列にバイト セマンティクスがあることを意味するわけではありません。

utf8 プラグマ全体が私にとって謎です。

おそらく、過剰に文書化されているため、混乱しているためです。ほとんどの開発者は、その目的がソース コードで Unicode リテラルを有効にすることであると述べている部分の後、読むのをやめることができます。

上記の例では、utf8::is_utf8($data) は OK を出力しますが、理由がわかりません。

を有効にする uni::perl のためですuse open qw(:utf8 :std);。を使用して STDIN から読み取った入力はすべて<>デコードされます。その後の正規化ステップはそれを変更しません。

于 2012-05-30T21:43:21.353 に答える