これは、Ubuntu Online、Fedora Online、Windows オンライン エミュレーター、MAC OS オンライン エミュレーターなど、複数の無料オンライン ワークステーションのいずれかを使用して、OnWorks 無料ホスティング プロバイダーで実行できるコマンド perluniintro です。
プログラム:
NAME
perluniintro - Perl Unicode の紹介
DESCRIPTION
このドキュメントでは、Unicode の一般的な考え方と、Perl で Unicode を使用する方法について説明します。 見る
Unicode のより詳細な処理については、「その他のリソース」を参照してください。
Unicode
Unicode は文字セット標準であり、Unicode のすべての書記体系を成文化することを計画しています。
世界、および他の多くのシンボル。
Unicode と ISO/IEC 10646 は、他のほとんどすべての最新のものを統一する協調規格です。
80 を超える書記体系と数百の言語をカバーする文字セット標準
商業的に重要なすべての現代言語を含みます。 最大のすべての文字
中国語、日本語、韓国語の辞書もエンコードされています。 基準は最終的に
250 を超える書記体系と数千の言語のほぼすべての文字をカバーしています。
Unicode 1.0 は 1991 年 6.0 月にリリースされ、2010 は XNUMX 年 XNUMX 月にリリースされました。
ユニコード 文字 抽象的な存在です。 特定の整数にバインドされていません
幅、特に C 言語の「char」ではありません。 Unicode は言語に依存せず、表示にも影響しません。
ニュートラル: テキストの言語をエンコードせず、一般的に定義しません
フォントまたはその他のグラフィック レイアウトの詳細。 Unicode は、文字と構築されたテキストで動作します
それらのキャラクターから。
Unicode は、「LATIN CAPITAL LETTER A」や「GREEK SMALL LETTER ALPHA」などの文字を定義し、
文字の一意の番号、この場合はそれぞれ 0x0041 と 0x03B1 です。 これらは
固有の番号が呼び出されます コード ポイント. コード ポイントは、基本的には
すべての可能な Unicode 文字のセット内の文字、したがって Perl では、用語
序数 と同じ意味で使われることが多いです。
Unicode 標準では、コード ポイントに XNUMX 進表記を使用することが推奨されています。 数字なら
0x0041 などはなじみがないので、後のセクション「XNUMX 進表記」を参照してください。
Unicode 標準では、「U+0041 LATIN CAPITAL LETTER A」という表記を使用して、
XNUMX 進コード ポイントと文字の規範名。
Unicode もさまざまな定義をしています。 プロパティ 「大文字」や
「小文字」、「XNUMX 進数」、または「句読点」。 これらのプロパティは、
キャラクターの名前。 さらに、キャラクターに対するさまざまな操作
大文字、小文字、および照合 (並べ替え) が定義されています。
ユニコード 論理的な 「キャラクター」は実際には複数の内部要素で構成されます 実際の
「文字」またはコードポイント。 西洋言語の場合、これは ベース
文字 ("LATIN CAPITAL LETTER A" など) に XNUMX つ以上続く 修飾子 (
「急性アクセントの組み合わせ」)。 この一連の基本文字と修飾子は、a と呼ばれます。
結合 文字 シーケンス. 一部の非西洋言語では、より複雑なモデルが必要です。
ユニコードが作成した 書記素 後にさらに洗練されたコンセプト
で 書記素 . たとえば、韓国語のハングル音節は XNUMX つの音節と見なされます。
論理文字ですが、ほとんどの場合、XNUMX つの実際の Unicode 文字で構成されます。
子音の後に内母音が続き、その後に子音が続きます。
これらの拡張書記素クラスターを「文字」と呼ぶかどうかは、あなたのポイントに依存します
見る。 あなたがプログラマーなら、おそらく、
XNUMX つの単位、つまり「文字」としてのシーケンス。 しかし、ユーザーの視点から見ると、全体
シーケンスは XNUMX つの「文字」と見なすことができます。
ユーザーの言語のコンテキスト。 このドキュメントでは、プログラマーの観点から説明します。
XNUMX つの「文字」は XNUMX つの Unicode コード ポイントです。
基本文字と修飾子の組み合わせによっては、 事前に作曲された 文字。
たとえば、シーケンス "LATIN CAPITAL
LETTER A」の後に「COMBINING ACUTE ACCENT」が続きます。これは「LATIN CAPITAL LETTER A」と呼ばれます。
ただし、これらの構成済みの文字は、一部の文字でのみ使用できます。
の組み合わせであり、主に Unicode と
レガシー規格 (ISO 8859 など)。 Unicode のようにシーケンスを使用すると、
より多くの潜在的な書記素を表現するための基本的なビルディング ブロック (コード ポイント) の数を減らす
クラスター。 同等のフォーム間の変換をサポートするために、さまざまな 正規化 フォーム
も定義されています。 したがって、「LATIN CAPITAL LETTER A WITH ACUTE」は 正規化 フォーム
作曲、(略称 NFC)、およびシーケンス「LATIN CAPITAL LETTER A」の後に続く
"COMBINING ACUTE ACCENT" は、同じ文字を表します。 正規化 フォーム 分解した
(NFD)。
従来のエンコーディングとの下位互換性のため、「すべての一意の番号
文字」のアイデアは少し崩壊します: 代わりに、「すべての文字に少なくとも XNUMX つの数字があります。
文字」。同じ文字が、いくつかのレガシーで異なる方法で表現される可能性があります
エンコーディング。 逆は正しくありません。一部のコード ポイントには、割り当てられた文字がありません。
まず、他の方法で使用されるブロック内に未割り当てのコード ポイントがあります。 第二に、そこで
真の文字を表さない特別な Unicode 制御文字です。
Unicode が最初に考案されたとき、世界中の文字はすべて
16 ビットワードを使用して表されます。 つまり、最大 0x10000 (または 65,536) 文字です。
0x0000 から 0xFFFF まで必要です。 これはすぐに間違っていることが判明し、Unicode 2.0 以降
(1996 年 21 月)、Unicode は 0 ビット (10xXNUMXFFFF) まで定義されており、Unicode
3.1 (2001 年 0 月) では、0xFFFF より上の最初の文字が定義されました。 最初の 10000xXNUMX 文字
と呼ばれます 飛行機 0、または Basic 多言語 飛行機 (BMP)。 Unicode 3.1、17 (はい、
全部で XNUMX) のプレーンが定義されましたが、定義されたプレーンが完全に満たされているとは言えません。
キャラクター、まだ。
新しい言語がエンコードされているとき、Unicode は通常、次の「ブロック」を選択します。
その文字の連続した未割り当てのコード ポイント。 これまでのコードポイント数
これらのブロックのエクストラは、常に 16 で割り切れます。
将来の成長のために未割り当てのままにします。 しかし、
後のリリースでは、利用可能なエクストラよりも多くのコード ポイントが必要であり、新しいブロックを作成する必要がありました。
オーバーフローを処理するために、最初の場所に隣接していない別の場所に割り当てられます。
したがって、「ブロック」が適切な組織化の原則ではないことが早い段階で明らかになりました。
そのため、「スクリプト」プロパティが作成されました。 (後で、改善されたスクリプト プロパティが追加されました。
まあ、「Script_Extensions」プロパティです。) オーバーフロー ブロックにあるコード ポイント
元のスクリプトと同じスクリプトを使用できます。 スクリプトの概念はより密接に適合します
自然言語の場合: 「ラテン」スクリプト、「ギリシャ」スクリプトなどがあります。 そしてあります
複数で使用される文字の「Common」など、いくつかの人為的なスクリプト
数学記号などのスクリプト。 スクリプトは通常、いくつかのさまざまな部分にまたがります。
ブロック。 スクリプトの詳細については、perlunicode の「スクリプト」を参照してください。 分裂
ブロックへの変換は存在しますが、それはほぼ完全に偶然です。
文字が割り当てられ、現在も割り当てられています。 (この段落には
これは紹介であるため、物事を単純化しすぎています。 Unicodeは実際にはそうではありません
言語をエンコードしますが、それらの書記体系、つまりスクリプトをエンコードします。 そしてXNUMXつのスクリプトは
多くの言語で使用されています。 Unicode は、実際には言語に関するものではないものもエンコードします。
「BAGGAGE CLAIM」のような記号など)。
Unicode コード ポイントは単なる抽象的な数値です。 これらのアブストラクトを入出力するため
数字、数字は エンコード or シリアル化 何とかして。 Unicode はいくつかの定義をしています
文字 エンコーディング フォーム、そのうちの UTF-8 が最も人気があります。 UTF-8 は可変長です
Unicode 文字を 1 ~ 4 バイトとしてエンコードするエンコーディング。 他のエンコーディングには UTF-16 が含まれます
UTF-32 およびそれらのビッグ エンディアンとリトル エンディアンのバリアント (UTF-8 はバイト順序に依存しません)。
ISO/IEC 10646 は、UCS-2 および UCS-4 のエンコード形式を定義しています。
エンコーディングの詳細については、たとえば、 代理 バイト
注文 マーク (BOM) は -- perlunicode を参照してください。
Perlの Unicode サポート
Perl v5.6.0 から、Perl は Unicode をネイティブに処理できるようになりました。 パール
ただし、v5.8.0 は、本格的な Unicode 作業向けの最初の推奨リリースです。 の
メンテナンス リリース 5.6.1 では、初期の Unicode の問題の多くが修正されました。
実装されていますが、たとえば、正規表現は依然として Unicode では機能しません。
5.6.1. Perl v5.14.0 は、Unicode サポートが (ほぼ) シームレスになった最初のリリースです
いくつかの落とし穴なしで統合可能 (例外は quotemeta のいくつかの違いであり、
これは Perl 5.16.0 から修正されています)。 このシームレスなサポートを有効にするには、「使用する必要があります。
feature 'unicode_strings'" ("use 5.012" 以上の場合は自動的に選択されます)。
機能を参照してください。 (5.14 では、多数のバグと Unicode 標準からの逸脱も修正されています。)
Perl v5.8.0 より前では、"use utf8" を使用して、その操作を宣言するために使用されていました。
現在のブロックまたはファイルは Unicode 対応になります。 このモデルは間違っていることが判明したか、
最も不器用:「Unicodeness」は、データに添付されるのではなく、データとともに運ばれるようになりました
操作。 Perl v5.8.0 から、明示的な "use
utf8" が必要です: Perl スクリプト自体が UTF-8 でエンコードされている場合は、スクリプトで UTF-8 を使用できます。
識別子名、および文字列と正規表現リテラルでは、「use utf8」と言います。
従来の 8 ビット データを含むスクリプトは破損するため、これはデフォルトではありません。 見る
utf8。
Perlの Unicode モデル
Perl は、5.6 より前の XNUMX ビット ネイティブ バイトの文字列と Unicode の文字列の両方をサポートします。
文字。 一般的な原則は、Perl がそのデータを XNUMX ビットのバイトとして保持しようとすることです。
しかし、Unicodeness が回避できなくなるとすぐに、データは
透過的に Unicode にアップグレードされました。 Perl v5.14.0 より前では、アップグレードは完全ではありませんでした。
透過的 (perlunicode の「The "Unicode Bug"」を参照)、および下位互換性のために、
「機能 'unicode_strings' を使用する」(機能を参照) または
「use 5.012」(またはそれ以上)が選択されています。
内部的に、Perl は現在、ネイティブの XNUMX ビット文字セットのいずれかを使用します。
platform (Latin-1 など) は、デフォルトで UTF-8 に設定され、Unicode 文字列をエンコードします。
具体的には、文字列内のすべてのコード ポイントが 0xFF 以下の場合、Perl はネイティブの
8 ビット文字セット。 それ以外の場合は、UTF-XNUMX を使用します。
通常、Perl のユーザーは、Perl がどのようにコードをエンコードするのかを知る必要も、気にする必要もありません。
内部文字列ですが、Unicode 文字列をストリームに出力するときに関連します
PerlIO レイヤーなし (「デフォルト」エンコーディングのレイヤー)。 このような場合、生のバイト
内部で使用されます (各文字列に応じてネイティブ文字セットまたは UTF-8)。
これらの文字列に
0x00FF を超える文字。
たとえば、
perl -e 'print "\x{DF}\n", "\x{0100}\x{DF}\n"'
ネイティブ バイトと UTF-8 のかなり役に立たない混合と、警告が生成されます。
幅広の文字で印刷...
UTF-8 を出力するには、「:encoding」または「:utf8」出力層を使用します。 プリペンディング
binmode(STDOUT, ":utf8");
このサンプル プログラムに追加すると、出力が完全に UTF-8 であることが保証され、
プログラムの警告。
標準ファイルハンドルの自動 UTF-8 化を有効にできます。デフォルトは「open()」です。
"-C" コマンド ライン スイッチまたは "PERL_UNICODE" のいずれかを使用してレイヤー、および @ARGV
環境変数。「-C」スイッチのドキュメントについては、perlrun を参照してください。
これは、Perl が他のソフトウェアが同じように動作することを期待していることを意味することに注意してください:
STDINはUTF-8であるべきだと信じ込まされましたが、STDINは別のものから入ってきます
command が UTF-8 でない場合、Perl は不正な形式の UTF-8 について文句を言うでしょう。
Unicode と I/O を組み合わせたすべての機能では、新しい PerlIO 機能も使用する必要があります。
ただし、ほとんどすべての Perl 5.8 プラットフォームは PerlIO を使用しています。
「perl -V」を実行し、「useperlio=define」を探します。
Unicode EBCDIC
Perl 5.8.0 では、EBCDIC プラットフォームでの Unicode のサポートが追加されました。 このサポートは、
以降のリリースでは失効していましたが、5.22 で復活しました。 Unicode サポートはやや多い
追加の変換が必要なため、実装が複雑です。 詳細については perlebcdic を参照してください
情報を表示します。
EBCDIC プラットフォームでは、内部 Unicode エンコード形式は UTF-8 ではなく UTF-EBCDIC です。
違いは、UTF-8 は ASCII 文字が UTF-8 にエンコードされるという点で「ASCII セーフ」であるためです。
現状のまま、UTF-EBCDIC は「EBCDIC セーフ」ですが、すべての基本文字 (
ASCII に相当するもの ("A"、"0"、"%"、 等々) はどちらも同じ
EBCDIC および UTF-EBCDIC。 多くの場合、ドキュメントでは「UTF-8」という用語を使用して、UTF-EBCDIC を意味します。
同じように。 これは、このドキュメントの場合です。
作成 Unicode
このセクションは、v5.22 以降の Perl に完全に適用されます。 事前の諸注意事項
リリースは、以下の「以前のリリースの警告」サブセクションにあります。
リテラルで Unicode 文字を作成するには、"\N{...}" 表記を二重引用符で囲んで使用します
文字列:
my $smiley_from_name = "\N{白い笑顔}";
私の $smiley_from_code_point = "\N{U+263a}";
同様に、正規表現リテラルで使用できます
$smiley =~ /\N{白い笑顔}/;
$smiley =~ /\N{U+263a}/;
実行時に以下を使用できます。
文字名 () を使用します。
私の$hebrew_alef_from_name
= charnames::string_vianame("ヘブライ文字アレフ");
私の $hebrew_alef_from_code_point = charnames::string_vianame("U+05D0");
当然、「ord()」は逆の処理を行います。つまり、文字をコード ポイントに変換します。
他のランタイム オプションもあります。 「pack()」を使用できます。
私の $hebrew_alef_from_code_point = pack("U", 0x05d0);
または、「chr()」を使用することもできますが、一般的なケースではあまり便利ではありません。
$hebrew_alef_from_code_point = chr(utf8::unicode_to_native(0x05d0));
utf8::upgrade($hebrew_alef_from_code_point);
引数が
0xFF を超えるため、上記は次のように記述できます。
$hebrew_alef_from_code_point = CHR(0x05d0);
0x5d0 は 255 を超えているためです。
"\x{}" と "\o{}" を使用して、コンパイル時にコード ポイントを二重に指定することもできます。
文字列を引用符で囲みますが、古い Perl との下位互換性のために、同じ規則が適用されます。
256 未満のコード ポイントには「chr()」を使用します。
「utf8::unicode_to_native()」は、Perl コードを EBCDIC プラットフォームに移植できるようにするために使用されます。
場合は省略できます。 本当に 誰もあなたのコードを非で使用したくないことを確認してください
アスキープラットフォーム。 Perl v5.22 から、ASCII プラットフォームでの呼び出しは最適化され、
したがって、追加してもパフォーマンスが低下することはまったくありません。 または、単に他のものを使用できます
それを必要としない構造。
これらすべての名前と数値コードを見つける方法については、「その他のリソース」を参照してください。
前 リリース 警告
v5.22 より前の EBCDIC プラットフォームでは、「\N{U+...}」を使用すると正しく機能しません。
v5.16 より前では、文字名で「\N{...}」を使用 (「U+...」コード ポイントではなく)
「use charnames :full」が必要です。
v5.14 より前のバージョンでは、"\N{...}" に文字名 (
"U+..." コード ポイント)。
「charnames::string_vianame()」は v5.14 で導入されました。 その前に、
"charnames::vianame()" は動作するはずですが、引数が "U+..." の形式の場合のみです。 君の
文字名によるランタイムUnicodeの最善の策は、おそらく次のとおりです。
文字名 () を使用します。
私の$hebrew_alef_from_name
= pack("U", charnames::vianame("ヘブライ文字アレフ"));
ハンドリング Unicode
Unicode の処理はほとんど透過的です。通常どおり文字列を使用するだけです。
「index()」、「length()」、「substr()」などの関数は Unicode 文字で機能します。
正規表現は Unicode 文字で動作します (perlunicode と perlretut を参照してください)。
Perl は書記素クラスタを別個の文字と見なすことに注意してください。たとえば、
print length("\N{LATIN CAPITAL LETTER A}\N{COMBINING ACUTE ACCENT}"),
"\n";
2 ではなく 1 を出力します。唯一の例外は、正規表現に「\X」があることです。
拡張書記素クラスターに一致します。 (したがって、正規表現の "\X" は、
両方の例の文字の完全なシーケンス。)
ただし、従来のエンコーディング、I/O、および
特定の特殊なケース:
XNUMX年の エンコーディング
レガシー データと Unicode を組み合わせる場合、レガシー データを Unicode にアップグレードする必要があります。
通常、レガシー データは ISO 8859-1 (または該当する場合は EBCDIC) であると想定されます。
「エンコード」モジュールは多くのエンコーディングを認識しており、変換を行うためのインターフェースを備えています
これらのエンコーディング間:
エンコード「デコード」を使用します。
$data = decode("iso-8859-3", $data); # レガシーから utf-8 に変換
Unicode I / O
通常、Unicode データを書き出す
print FH $some_string_with_unicode, "\n";
Unicode 文字列を内部的にエンコードするために Perl がたまたま使用する raw バイトを生成します。
Perl の内部エンコーディングは、システムと、どの文字がたまたま含まれているかによって異なります。
当時の弦。 いずれかの文字がコード ポイント 0x100 以上にある場合、
警告が表示されます。 出力がエンコーディングで明示的にレンダリングされるようにするには、
希望し、警告を回避するには、目的のエンコーディングでストリームを開きます。 いくつか
例:
open FH, ">:utf8", "ファイル";
open FH, ">:encoding(ucs2)", "ファイル";
open FH, ">:encoding(UTF-8)", "ファイル";
open FH, ">:encoding(shift_jis)", "ファイル";
すでに開いているストリームでは、「binmode()」を使用します。
binmode(STDOUT, ":utf8");
binmode(STDOUT, ":encoding(ucs2)");
binmode(STDOUT, ":encoding(UTF-8)");
binmode(STDOUT, ":encoding(shift_jis)");
エンコーディング名の一致は緩い: 大文字と小文字は関係なく、多くのエンコーディングには
いくつかの別名。 ":utf8" レイヤーは、常にそのように正確に指定する必要があることに注意してください。
それは エンコーディング名の緩やかな一致の対象となります。 また、現在
":utf8" は入力に対して安全ではありません。
確かに有効な UTF-8; 代わりに ":encoding(utf-8)" (ハイフンの有無にかかわらず) を使用する必要があります。
":utf8" レイヤーについては PerlIO を参照してください。
":encoding()" 層、および Encode::"Encode" でサポートされている多くのエンコーディングでサポート
モジュールを開きます。
たまたま Unicode またはレガシーのいずれかでエンコードされていることがわかっているファイルを読み取る
encodings は、Perl から見れば魔法のようにデータを Unicode に変換しません。 そのためには、
ファイルを開くときに適切なレイヤーを指定する
open(my $fh,'<:encoding(utf8)', 'なんでも');
私の $line_of_unicode = <$fh>;
open(my $fh,'<:encoding(Big5)', 'なんでも');
私の $line_of_unicode = <$fh>;
I/O レイヤーは、"open" プラグマを使用してより柔軟に指定することもできます。 オープンを参照、または
次の例を見てください。
open ':encoding(utf8)'; を使用してください。 # 入力/出力のデフォルト エンコーディングは
#UTF-8
X, ">ファイル" を開く;
X を印刷 CHR(0x100), "\n";
X を閉じます。
Y を開いて、"
printf "%#x\n", ord( ); # これは 0x100 を出力するはずです
Yを閉じます。
「open」プラグマを使用すると、「:locale」レイヤーを使用できます
BEGIN { $ENV{LC_ALL} = $ENV{LANG} = 'ru_RU.KOI8-R' }
# :locale は、次のようなロケール環境変数をプローブします
#LC_ALL
open OUT を使用 => ':locale'; #ルスキー・パルスキー
open(O, ">koi8");
プリント O CHR(0x430); # Unicode キリル小文字 A = KOI8-R 0xc1
Oを閉じます。
オープン(私、 "
printf "%#x\n", ord( ), "\n"; # これは 0xc1 を出力するはずです
私を閉じます。
これらのメソッドは、データを I/O ストリームに変換する透過的なフィルタを I/O ストリームにインストールします。
ストリームから読み込まれるときに指定されたエンコーディング。 結果は常に Unicode です。
open プラグマは、デフォルトのレイヤーを設定することにより、プラグマの後のすべての「open()」呼び出しに影響します。
特定のストリームのみに影響を与えたい場合は、明示的なレイヤーを「open()」で直接使用します
コール。
"binmode()" を使用して、既に開いているストリームのエンコーディングを切り替えることができます。 「ビンモード」を参照
perlfuncで。
現在、「:locale」は「open()」と「binmode()」では機能せず、「open」でのみ機能します。
プラグマ。 ":utf8" および ":encoding(...)" メソッドは、すべての "open()" で機能します。
「binmode()」、および「open」プラグマ。
同様に、出力ストリームでこれらの I/O レイヤーを使用して、Unicode を自動的に変換できます。
ストリームに書き込まれるときに、指定されたエンコーディングに変換されます。 たとえば、次の
スニペットは、ファイル「text.jis」(ISO-2022-JP、別名 JIS としてエンコード) の内容を
UTF-8 としてエンコードされたファイル「text.utf8」:
open(my $nihongo, '<:encoding(iso-2022-jp)', 'text.jis');
open(my $unicode, '>:utf8', 'text.utf8');
while (<$日本語>) { print $unicode $_ }
「open()」と「open」プラグマの両方によるエンコーディングの命名により、柔軟な
名前: 「koi8-r」と「KOI8R」の両方が理解されます。
ISO、MIME、IANA、およびその他のさまざまな標準化によって認識される一般的なエンコーディング
組織が認識されます。 より詳細なリストについては、Encode::Supported を参照してください。
「read()」は文字を読み取り、文字数を返します。 「seek()」と「tell()」
"sysread()" および "sysseek()" と同様に、バイト カウントで動作します。
入力時に変換を行わないというデフォルトの動作のため、次の場合に注意してください。
デフォルト層がないため、展開し続けるコードを誤って記述しやすい
データを繰り返しエンコードすることにより、ファイル:
# 悪いコードの警告
F、「ファイル」を開きます。
ローカル $/; ## 8 ビット文字のファイル全体を読み込む
$t = ;
Fを閉じます。
open F, ">:encoding(utf8)", "ファイル";
F $t; を印刷します。 ## 出力時に UTF-8 に変換
Fを閉じます。
このコードを XNUMX 回実行すると、 file 8 回 UTF-XNUMX でエンコードされます。 使用
open ':encoding(utf8)'" を使用すると、バグを回避できたはずです。 file
UTF-8 として入力する場合。
注意: ":utf8" および ":encoding" 機能は、Perl が でビルドされている場合にのみ機能します
ほとんどのシステムでデフォルトとなっている PerlIO。
表示 Unicode As テキスト
Unicode を含む Perl スカラーを単純な ASCII (または
EBCDIC) テキスト。 次のサブルーチンは、その引数を変換して、Unicode 文字が
コード ポイントが 255 より大きいものは、"\x{...}"、制御文字 (など) として表示されます。
"\n") は "\x.." として表示され、残りの文字はそれ自体として表示されます。
サブnice_string {
加入(""、
map { $_ > 255 # ワイド文字の場合...
? sprintf("\\x{%04X}", $_) # \x{...}
: chr($_) =~ /[[:cntrl:]]/ # そうでなければ制御文字...
? sprintf("\\x%02X", $_) # \x..
: quotemeta(chr($_)) # そうでなければ引用または自分自身として
} unpack("W*", $_[0])); # Unicode 文字をアンパック
}
たとえば、
nice_string("foo\x{100}bar\n")
文字列を返します
「foo\x{0100}bar\x0A」
これは印刷する準備ができています。
(ここでは、"\\N{}" の代わりに "\\x{}" が使用されています。
ネイティブ値は次のとおりです。)
Special ケース
· ビット補数演算子 ~ And vec()
ビット補数演算子「~」を文字列で使用すると、驚くべき結果が生じる場合があります
序数値が 255 を超える文字が含まれています。このような場合、結果は次のようになります。
文字の内部エンコーディングとは一致しますが、それ以外とはほとんど一致しません。 そう
それをしないでください。 同様に「vec()」の場合: 内部でエンコードされた
コード ポイント値ではなく、Unicode 文字のビット パターン。
おそらくあなたが望むものではありません。
· Perl の内部エンコーディングの覗き見
Perl の通常のユーザーは、Perl が特定の Unicode 文字列をどのようにエンコードするかを気にするべきではありません
(Unicode を使用して文字列の内容を取得する通常の方法は、入力を介して
および出力 - 常に明示的に定義された I/O レイヤーを介する必要があります)。 しかし、もしあなたがしなければならないなら、
舞台裏を見るには XNUMX つの方法があります。
Unicode 文字の内部エンコーディングを覗く XNUMX つの方法は、次を使用することです。
"unpack("C*", ..." は、文字列エンコーディングがたまたま何であれ、そのバイトを取得します。
「unpack("U0..", ...)」で UTF-8 エンコーディングのバイトを取得します。
# これは、UTF-4 バイト 80xc8 0x4 に対して c0 80 を出力します
print join(" ", unpack("U0(H2)*", pack("U", 0x100))), "\n";
さらに別の方法は、Devel::Peek モジュールを使用することです。
perl -MDevel::Peek -e 'Dump(CHR(0x100))'
これは、FLAGS の「UTF8」フラグと、UTF-8 バイトと Unicode 文字の両方を示しています。
「PV」。 このドキュメントの後半にある「utf8::is_utf8()」に関する議論も参照してください。
機能。
高機能 トピック
· 文字列等価
文字列の等価性の問題は、Unicode ではいくぶん複雑になります。
「等しい」という意味ですか?
(「LATIN CAPITAL LETTER A WITH ACUTE」は「LATIN CAPITAL LETTER A」と同じですか?)
簡単な答えは、デフォルトでは、Perl は同等性 ("eq"、"ne") のみを比較するということです。
文字のコードポイントについて。 上記の場合、答えはノーです (なぜなら 0x00C1
!= 0x0041)。 ただし、場合によっては、大文字の A はすべて等しいと見なす必要があります。
いずれにせよAです。
長い答えは、文字の正規化と大文字小文字を考慮する必要があるということです
問題: Unicode::Normalize、Unicode Technical Report #15、Unicode Normalization を参照
フォームhttp://www.unicode.org/unicode/reports/tr15> のケース マッピングに関するセクション
ユニコード標準http://www.unicode.org>.
Perl 5.8.0 以降、「完全な」大文字小文字の折り畳み シミュレーション例 マッピング/特殊ケーシング is
実装されていますが、バグは "qr//i" に残っており、5.14 までにほとんど修正されています。
5.18までに本質的に完全に。
・文字列照合
人々は、自分の文字列が適切にソートされていること、または Unicode の用語が言うように照合されていることを好みます。
繰り返しになりますが、照合とはどういう意味ですか?
("LATIN CAPITAL LETTER A WITH ACUTE" は "LATIN CAPITAL LETTER A の前または後に来ますか?
WITH GRAVE"?)
簡単に言えば、Perl はデフォルトで文字列 ("lt"、"le"、"cmp"、"ge"、
"gt") は、文字のコード ポイントのみに基づいています。 上記の場合、答えは
0x00C1 > 0x00C0 であるため、「後」です。
長い答えは「場合による」というものであり、それなしでは良い答えは得られません。
(少なくとも)言語の文脈を知っている。 Unicode::Collate を参照してください。 Unicode
照合 アルゴリズム <http://www.unicode.org/unicode/reports/tr10/>
その他
· 文字範囲とクラス
正規表現の括弧付き文字クラスの文字範囲 (例: "/[az]/")
また、"tr///" ("y///" とも呼ばれます) 演算子は魔法のように Unicode を認識しません。
これが意味することは、「[A-Za-z]」が魔法のように「すべてアルファベット順」を意味するわけではないということです。
文字」(8 ビット文字の場合でも、という意味ではありません。
ロケール (perllocale) を使用する場合は、"/[[:alpha:]]/" を使用します。 そうでない場合は、8ビット対応の
プロパティ "\p{alpha}")。
"\p" (およびその逆 "\P") で始まるすべてのプロパティは、実際には文字です。
Unicode 対応のクラス。 それらは数十あります。perluniprops を参照してください。
v5.22 以降、通常のエンドポイントとして Unicode コード ポイントを使用できます。
式パターンの文字範囲。範囲にはすべての Unicode コードが含まれます。
それらの終点の間にある点を含みます。
qr/ [\N{U+03]-\N{U+20}] /x
コード ポイント "\N{U+03}"、"\N{U+04}"、...、"\N{U+20}" が含まれます。
(Perl v5.24 では、この動作を "tr///" の範囲に拡張する予定です。)
· 文字列から数値への変換
Unicode は、
アラビア数字やインド数字など、おなじみの 0 ~ 9 です。 Perl は文字列をサポートしていません-
ASCII 0 から 9 (および ASCII "a" から "f" の場合) 以外の数字の数値への変換
XNUMX 進数)。 Unicode 文字列から安全に変換するには、"数値()"で
ユニコード::UCD。
質問 自律的AI 答え
· 私の古いスクリプトは壊れますか?
おそらくそうではありません。 どういうわけかUnicode文字を生成していない限り、古い
行動は維持されるべきです。 変更された唯一の動作について
Unicode の生成を開始できるのは、"chr()" の古い動作です。
引数が 255 を超えると、255 を法とする文字が生成されました。"CHR(300)」、たとえば
に等しい "CHR(45)" または "-" (ASCII)、現在は LATIN CAPITAL LETTER I WITH BREVE です。
· スクリプトを Unicode で動作させるにはどうすればよいですか?
Unicode を生成するまで何も変わらないため、必要な作業はほとんどありません。
データ。 最も重要なことは、入力を Unicode として取得することです。 そのためには、以前の
I/O の議論。 完全にシームレスな Unicode サポートを取得するには、「使用機能」を追加します
'unicode_strings'" (または "use 5.012" 以上) をスクリプトに追加します。
· 自分の文字列が Unicode かどうかを知るにはどうすればよいですか?
あなたは気にする必要はありません。 ただし、Perl が 5.14.0 より前であるか、そうでない場合は可能です。
"use feature 'unicode_strings'" または "use 5.012" (またはそれ以降) を指定しました。
128 ~ 255 の範囲のコード ポイントのルールは、
それらが含まれている文字列が Unicode であるかどうか。 (「Unicode の場合」を参照してください。
起こらない」を perlunicode で。)
文字列が Unicode かどうかを判断するには、次を使用します。
print utf8::is_utf8($string) ? 1 : 0, "\n";
ただし、これは、文字列内の文字のいずれかが必要であることを意味するものではないことに注意してください
UTF-8 でエンコードされているか、いずれかの文字のコード ポイントが 0xFF (255) より大きいこと
または 0x80 (128)、または文字列に文字が含まれていることさえあります。 すべての「is_utf8()」
$string に付加された内部の「utf8ness」フラグの値を返すことです。
フラグがオフの場合、スカラーのバイトは XNUMX バイトのエンコーディングとして解釈されます。
フラグがオンの場合、スカラー内のバイトは (可変長、
マルチバイトの可能性がある) UTF-8 でエンコードされた文字のコード ポイント。 に追加されたバイト数
UTF-8 でエンコードされた文字列は、自動的に UTF-8 にアップグレードされます。 非 UTF-8 と
UTF-8 スカラーがマージされます (二重引用符で囲まれた補間、明示的な連結、または
printf/sprintf パラメータ置換)、結果はコピーのように UTF-8 でエンコードされます
のバイト文字列が UTF-8 にアップグレードされました: たとえば、
$a = "ab\x80c";
$b = "\x{100}";
print "$a = $b\n";
出力文字列は UTF-8 でエンコードされた "ab\x80c = \x{100}\n" になりますが、$a はバイトのままです-
エンコードされます。
文字列の長さではなく、文字列のバイト長を知る必要がある場合があります。
文字の長さ。 そのためには、"Encode::encode_utf8()" 関数または
"bytes" プラグマと "length()" 関数:
私の $unicode = CHR(0x100);
印刷長($unicode), "\n"; # は 1 を出力します
エンコードが必要です。
print length(Encode::encode_utf8($unicode)),"\n"; # 2 を出力します
バイトを使用します。
印刷長($unicode), "\n"; # 2 も出力します
# (UTF-0 の 4xC0 80x8)
バイトなし;
· ファイルのエンコーディングを調べるにはどうすればよいですか?
Encode::Guess を試すこともできますが、いくつかの制限があります。
· 特定のエンコーディングで無効なデータを検出するにはどうすればよいですか?
「エンコード」パッケージを使用して変換してみてください。 例えば、
エンコード 'decode_utf8' を使用します。
if (eval {decode_utf8($string, Encode::FB_CROAK); 1 }) {
# $string は有効な utf8 です
場合} else {
# $string は無効です utf8
}
または、「unpack」を使用してデコードを試みます。
警告を使用します。
@chars = unpack("C0U*", $string_of_bytes_that_I_think_is_utf8);
無効な場合、「不正な UTF-8 文字」警告が生成されます。 「C0」は「プロセス」を意味します
文字ごとの文字列」。それがなければ、「unpack("U*", ...)」は機能します
「U0」モード (フォーマット文字列が「U」で始まる場合のデフォルト) で、それは戻ります
ターゲット文字列の UTF-8 エンコーディングを構成するバイト。
常に動作します。
· バイナリ データを特定のエンコーディングに、またはその逆に変換するにはどうすればよいですか?
これはおそらく、あなたが思っているほど役に立ちません。 通常、その必要はありません。
ある意味では、あなたが求めていることはあまり意味がありません: エンコーディングは
文字、およびバイナリデータは「文字」ではないため、「データ」をいくつかに変換します
エンコーディングは、どの文字セットとエンコーディングを知っていない限り意味がありません
バイナリ データが入っています。この場合、単なるバイナリ データではありません。
を介して解釈する必要があることがわかっているバイトの生のシーケンスがある場合
特定のエンコーディングでは、「エンコード」を使用できます。
Encode'from_to'を使用します;
from_to($data, "iso-8859-1", "utf-8"); # latin-1 から utf-8 へ
「from_to()」の呼び出しは $data のバイトを変更しますが、
Perl に関する限り、文字列の性質が変更されました。 前も後も
呼び出し、文字列 $data には 8 ビット バイトの束が含まれています。 パールがいる限り
関連して、文字列のエンコーディングは「システムネイティブの8ビットバイト」のままです。
これを架空の「翻訳」モジュールに関連付けることができます。
翻訳を使用します。
私の $phrase = "はい";
Translate::from_to($phrase, 'english', 'deutsch');
## 句に「Ja」が含まれるようになりました
文字列の内容は変わりますが、文字列の性質は変わりません。 Perlはしません
文字列の内容が
肯定的。
データの変換に戻ります。 システムのネイティブ 8 ビットにデータがある (または必要な) 場合
エンコーディング (例: Latin-1、EBCDIC など)、pack/unpack を使用して変換することができます。
ユニコード。
$native_string = pack("W*", unpack("U*", $Unicode_string));
$Unicode_string = pack("U*", unpack("W*", $native_string));
一連のバイトがある場合は、 知っています は有効な UTF-8 ですが、Perl はまだ認識していません。
Perl を信者にすることもできます。
エンコード 'decode_utf8' を使用します。
$Unicode = decode_utf8($bytes);
または:
$Unicode = pack("U0a*", $bytes);
UTF-8 シーケンスを構成するバイトを見つけるには、
@bytes = unpack("C*", $Unicode_string)
そして、あなたは整形式のUnicodeを作成することができます
$Unicode_string = pack("U*", 0xff, ...)
· Unicode を表示するにはどうすればよいですか? Unicode を入力するにはどうすればよいですか?
見るhttp://www.alanwood.net/unicode/>および
<http://www.cl.cam.ac.uk/~mgk25/unicode.html>
· 従来のロケールでは Unicode はどのように機能しますか?
Perl v8 以降、ロケールが UTF-5.20 ロケールの場合、Perl はすべてのロケールで適切に動作します。
ソートを扱う「LC_COLLATE」と「cmp」演算子を除くカテゴリ。
他のロケールでは、Perl 5.16 以降、指定できます。
ロケール ':not_characters' を使用します。
Perl がうまく動作するようにします。 キャッチは、あなたがから翻訳しなければならないということです
Unicode との間でロケール文字セットを自分で設定します。 方法については、上記の「Unicode I/O」を参照してください。
open':locale'を使用します;
これを達成するためですが、完全な詳細は perllocale の「Unicode and UTF-8」にあります。
「:not_characters」を指定しない場合に発生する落とし穴を含みます。
16進数 表記法
Unicode 標準では、XNUMX 進表記の使用が好まれます。
Unicode を 256 文字のブロックに分割すること。 XNUMX進数も単純に短い
XNUMX進数より。 XNUMX 進数も使えますが、XNUMX 進数の使い方を学ぶだけです。
Unicode 標準で生活が楽になります。 「U+HHHH」表記は XNUMX 進数を使用します。
例。
「0x」プレフィックスは 0 進数を意味し、数字は 9 ~ XNUMX です af (または AF、ケース
関係ない)。 各 XNUMX 進数は XNUMX ビット、つまり半バイトを表します。 「プリント
0x..., "\n"" は XNUMX 進数を XNUMX 進数で表示し、"printf "%x\n", $decimal" は XNUMX 進数で表示します。
XNUMX 進数を XNUMX 進数で表示します。 XNUMX進数の「XNUMX進数」だけがある場合
数、「hex()」関数を使用できます。
0x0009、「\n」を印刷します。 #9
print 0x000a, "\n"; #10
print 0x000f, "\n"; #15
0x0010、「\n」を印刷します。 #16
0x0011、「\n」を印刷します。 #17
0x0100、「\n」を印刷します。 #256
0x0041、「\n」を印刷します。 #65
printf "%x\n", 65; #41
printf "%#x\n", 65; # 0x41
print hex("41"), "\n"; #65
さらに その他情報
· Unicode コンソーシアム
<http://www.unicode.org/>
· Unicode FAQ
<http://www.unicode.org/unicode/faq/>
· ユニコード用語集
<http://www.unicode.org/glossary/>
· Unicode 推奨読書リスト
Unicode Consortium には記事や書籍のリストがあり、その中には多くの情報を提供するものもあります。
Unicode のより詳細な処理:http://unicode.org/resources/readinglist.html>
· ユニコードの便利なリソース
<http://www.unicode.org/unicode/onlinedat/resources.html>
· HTML、フォント、Web ブラウザ、およびその他のアプリケーションでの Unicode および多言語サポート
<http://www.alanwood.net/unicode/>
· Unix/Linux の UTF-8 および Unicode FAQ
<http://www.cl.cam.ac.uk/~mgk25/unicode.html>
· 従来の文字セット
<http://www.czyborra.com/>>http://www.eki.ee/letter/>
· を使用して、Unicode データ ファイルからさまざまな情報を調べることができます。
「Unicode::UCD」モジュール。
UNICODE IN OLDER パールズ
Perl を 5.8.0 以降にアップグレードできない場合でも、Unicode を実行できます。
モジュール「Unicode::String」、「Unicode::Map8」、および「Unicode::Map」を使用した処理、
CPAN から入手できます。 GNU recode がインストールされている場合は、Perl も使用できます。
文字変換のフロントエンド「Convert::Recode」。
以下は、ISO 8859-1 (Latin-1) バイトから UTF-8 バイトへの高速変換です。
戻ると、コードは古い Perl 5 バージョンでも機能します。
# ISO 8859-1 から UTF-8
s/([\x80-\xFF])/chr(0xC0|ord($1)>>6).chr(0x80|ord($1)&0x3F)/eg;
# UTF-8 から ISO 8859-1
s/([\xC2\xC3])([\x80-\xBF])/chr(ord($1)<<6&0xC0|ord($2)&0x3F)/eg;
onworks.net サービスを使用してオンラインで perluniintro を使用する
