このドキュメントでは、次のトピックについて説明します。
Natural では、フォーマット U および U 定数を使用して Unicode 文字列を指定できます。
フォーマット U
フォーマット U を使用して、Unicode 文字列を保持するデータを定義できます。 Natural データフォーマット U は、内部的には UTF-16 です。
『プログラミングガイド』の「ユーザー定義変数のフォーマットおよび長さ」も参照してください。
U 定数
接頭辞 "U" を使用して、Unicode 定数を定義できます。 次に例を示します。
U'Äpfel'
接頭辞 "UH" は、Unicode 定数を 16 進形式で定義するために使用できます。 Unicode 標準で定義されているように、4 桁の 16 進数は 1 つの UTF-16 コード単位を表します。 したがって、全体の長さは 4 の倍数になります。 例えば、次の 16 進形式が必要であるとします。
U'Äpfel'
"Ä"、"p"、"f"、"e"、および "l" の UTF-16 コード単位("U+00C4"、"U+0070"、"U+0066"、"U+0065"、および "U+006C")が必要であり、これらを次の 16 進数の文字列に結合する必要があります。
UH'00C4007000660065006C'
『プログラミングガイド』の「Unicode 定数」も参照してください。
データフォーマット U は、エンディアンに依存します。 フォーマット B と U 間で移動する場合は、これを考慮する必要があります。
A フォーマットと比較した U フォーマットの利点は、さまざまな言語の文字の任意の組み合わせを保持でき、デフォルトコードページ(システム変数 *CODEPAGE
の値)に依存しない点です。 さらに、U フォーマットでは、異なるプラットフォーム間でのデータの共有が簡単です。変換(例えば、EBCDIC から ASCII へ)は必要ありません。
一方、U フォーマットデータは、A フォーマットデータよりも多くのメモリが消費されます。 ほとんどの文字列をシングルバイトエンコードで表すことができる言語の場合、U フォーマットでは、以前に必要だったスペースの 2 倍のスペースが文字列によって占められるようになります。 ただし、東アジア言語の場合は、通常、メモリ消費は増加しません。
基本的に、A フォーマットを使用できるステートメントのほとんどで、U フォーマットを使用できます。 ただし、ステートメントのオペランドとして Natural オブジェクト名が与えられる場合(CALLNAT
ステートメントなど)、Natural オブジェクト名は A フォーマットであるため、U を使用できません。 特定のステートメントの詳細については、『ステートメント』ドキュメントを参照してください。
基本的に、A および U フォーマットは、1 つのステートメント内で一緒に使用できます。次に例を示します。
EXAMINE S FOR P WITH DELIMITER D REPLACE R
S
は U フォーマット、P
、D
、および R
は A フォーマットです。
上記の例では、変数 P
、D
、および R
がターゲットフォーマット U に一時的に変換されてから、EXAMINE
ステートメントが実際に実行されます。 Unicode からコードページ、またはその逆の変換では、ICU 機能を呼び出す必要があります。 この変換には、コンピュータの時間およびメモリが追加で必要になります。 この短所は、大きな変数の場合にさらに顕著になります。
頻繁な変換を避けるために、1 つのステートメント内では 1 つのフォーマットのみを使用することをお勧めします。 上記の例のすべてのオペランドが U フォーマットまたは A フォーマットで指定されている場合は、変換は必要ありません。 ただし、U
オペランドのみを指定することを選択した場合は、遅くなります。このオペランドタイプでは、その性質によってリソースが多く消費されるためです。この場合、1 文字が、A フォーマットで使用される 1 バイトではなく、2 バイトでコード化されます。
変換(特に、U フォーマットから A フォーマットへ)では、ターゲットコードページで文字を表現できないというリスクが常にあります。 例えば、Unicode 文字 "U+05D0"(ヘブライ文字のアレフ)をコードページ IBM01140(英語)に変換するとします。 この文字はコードページ IBM01140 に含まれていないため、このコードページの置換文字か、またはコードページの定義時に NATCONFG
に指定されたプレースホルダ(メインフレームのみ)が使用されます。 パラメータ CPCVERR
が "ON" に設定されている場合は、変換エラーを示すエラーメッセージがこの場合に表示されます。 いずれの場合にも、元の情報は失われます。
Unicode を使用する場合、特に次のステートメントに影響します。
Unicode での正規化:バイナリでの等価比較が可能な形式へデータを変換するために、同等のシーケンスの代替表現をテキストデータから削除するプロセス。 Unicode 標準では、さまざまな正規化形式が定義されています。 Unicode 文字列の正規分解の結果の正規化形式の後に、可能であればプライマリ合成による分解されたすべてのシーケンスに置き換わるものを付けた形式は、"合成済み正規化形式"(NFC)と呼ばれます。
Natural では、Unicode 文字を部分的に切り捨てることなく文字列処理を実行できるように、すべての Unicode データは NFC フォーマットであることが前提となっています。 Natural 変換処理では、結果として生じる Unicode
文字列は NFC であることが保証されます。 Natural の外部から Unicode データを受け取り、そのデータが NFC フォーマットであることが保証されない場合は、MOVE NORMALIZED
ステートメントを適用できます。
例:
文字シーケンス | NFC |
---|---|
ê (U+00EA) | ê (U+00EA) |
e (U+0065) + ^ (U+0302) | ê (U+00EA) |
注意:
NFC フォーマットの 2 つ以上の文字列を連結した場合、NFC フォーマットにならない場合があります。
MOVE
ステートメントを使用して文字列を U から A へ、またはその逆に移動するときに、Unicode とデフォルトコードページ(システム変数 *CODEPAGE
の値)の間の暗黙的な変換が実行されます。
さらに、異なるコードページ間の変換、または使用可能なコードページから Unicode への変換、およびその逆への変換に、MOVE ENCODED
ステートメントを使用できます。 これは、Natural の外部からのデータがデフォルトコードページとは異なるコードページでコード化されている場合に役立ちます。 しかし、デフォルトコードページと Unicode 間の変換についても、GIVING
節での潜在的な変換エラーを取得する場合は、このステートメントを使用できます。この場合は、CPCVERR
が "ON" に設定されている場合に、MOVE
ステートメントはランタイムエラーで停止します。
文字を変換できない場合に、この文字に対して置換文字が使用されるか変換が失敗するかは、CPCVERR
パラメータの設定によって異なります。 Windows、UNIX、および OpenVMS プラットフォームでは、Unicode からデフォルトコードページ(CP
)への変換について ICU によって定義されたデフォルトの置換文字は、プロファイルパラメータ SUBCHAR
を使用して変更できます。
このステートメントは、U データから UTF-8 フォーマットへの変換についても使用できます。
注意:
デフォルトコードページとは異なるコードページにデータを変換する場合は、このデータを I/O で使用しないことをお勧めします。 I/O は、デフォルトコードページでのみ意味があります。
"grapheme" は、ユーザーが一般に文字と見なすものです。 ほとんどの場合、Unicode コードポイントは書記素ですが、書記素が複数の Unicode コードポイントで構成される場合もあります。 例えば、1 つの基底文字と 1 つ以上の結合文字のシーケンスは書記素です。
例:"a" (U+0061) + "." (U+0323) + "^" (U+0302) は、次のように表示される 1 つの書記素を定義します。
注意:
基底文字/結合文字のシーケンスが正規化される場合、このことはシーケンスが常に合成済み文字によって置き換えられることを意味しません。すべての文字に合成済みフォーマットがあるわけではないためです。
"補助コードポイント" は、"U+10000" と "U+10FFFF" の間の Unicode コードポイントです。 補助コードポイントは UTF-16 であり、2 つのコード単位で構成されるサロゲートペアによって表されます。ペアの最初の値は "上位サロゲートコード単位"、2 番目は "下位サロゲートコード単位" です。 このような文字は一般的にはまれですが、中国語や日本語の人名の一部などで使用される場合があります。したがって、東アジアの国の行政アプリケーションでは、一般にこれらの文字のサポートが必要です。
EXAMINE
とその SUBSTRING
オプションなどの文字列操作ステートメントは、UTF-16 コード単位を処理します。 コードによって書記素またはサロゲートペアが分離されないようにすることは、ユーザーの責任です。
ただし、EXAMINE
ステートメントの節 CHARPOSITION
および CHARLENGTH
(「構文 3 - Unicode 書記素用の EXAMINE」を参照)を使用して、書記素の UTF-16 コード単位での開始位置および長さを求めることができます。 結果の値は、SUBSTRING
呼び出しに使用できます。 これらの節を使用して、書記素ごとに文字列をスキャンできます。
例:
DEFINE DATA LOCAL 1 #UNICODE-STRING (U15) 1 #CODE-UNIT-INDEX (N4) 1 #CODE-UNIT-LEN (N4) 1 #GRAPHEME-NUMBER (N4) END-DEFINE MOVE U'' TO #UNICODE-STRING #GRAPHEME-NUMBER := 1 REPEAT EXAMINE FULL VALUE OF #UNICODE-STRING FOR CHARPOSITION #GRAPHEME-NUMBER GIVING POSITION IN #CODE-UNIT-INDEX GIVING LENGTH IN #CODE-UNIT-LEN DISPLAY #UNICODE-STRING #GRAPHEME-NUMBER #CODE-UNIT-INDEX #CODE-UNIT-LEN #GRAPHEME-NUMBER := #GRAPHEME-NUMBER + 1 WHILE #CODE-UNIT-INDEX NE 0 END-REPEAT END
上記のプログラム例の出力は、次のとおりです。
Page 1 05-12-15 09:33:49 #UNICODE-STRING #GRAPHEME-NUMBER #CODE-UNIT-INDEX #CODE-UNIT-LEN --------------- ---------------- ---------------- -------------- 1 1 1 2 2 2 3 4 1 4 5 3 5 8 1 6 9 3 7 12 1 8 13 3 9 0 0
XML 文書では、文書のエンコードに関する情報を XML 文書ヘッダーに含めることができます(例えば、<?xml version="1.0" encoding="UTF-8" ?>
)。 XML 文書にこの情報が含まれている場合、Windows、UNIX、および OpenVMS プラットフォームでの XML 文書の解析には、受け取りフィールドがフォーマット U ではない場合は、XML 文書ヘッダー内で指定されたコードページから
Natural のデフォルトコードページ(システム変数 *CODEPAGE
の値)への変換が常に含まれます。
メインフレームプラットフォームでは、文書がすでに UTF-16 でエンコードされていない場合、解析される文書は常に内部的に UTF-16 に変換されます。
詳細については、PARSE XML
ステートメントの説明を参照してください。
『プログラミングガイド』の「インターネットおよび XML アクセス用のステートメント」も参照してください。
REQUEST DOCUMENT
ステートメントを使用したデータ転送では、通常、コードページ変換は呼び出されません。 送信データ/受信データを特定のコードページでエンコードする場合は、REQUEST DOCUMENT
ステートメントの DATA ALL
節/RETURN PAGE
節を使用して指定できます。
詳細については、REQUEST DOCUMENT
ステートメントの説明を参照してください。
『プログラミングガイド』の「インターネットおよび XML アクセス用のステートメント」も参照してください。
メインフレームプラットフォームでは、DEFINE PRINTER
ステートメントに CODEPAGE
節があり、出力レポートデータをデフォルトコードページ(システム変数 *CODEPAGE
の値)とは異なるコードページに変換できます。 Windows、UNIX、および OpenVMS プラットフォームでは、DEFINE PRINTER
ステートメントにそのような節はありません。CODEPAGE
節が定義された場合、Windows、UNIX、および OpenVMS プラットフォームでは無視されます。
RPC 経由での Unicode フォーマットでのデータ交換がサポートされています。 CALLNAT
ステートメントの説明を参照してください。
U データがビッグエンディアンエンコードのプラットフォームからリトルエンディアンエンコードのプラットフォームへ、またはその逆に送信される場合、エンコードは受信プラットフォームのエンコードに準拠するように変更されます。 例えば、リトルエンディアンエンコードの U データがビッグエンディアンのプラットフォームに到着した場合、このデータはビッグエンディアンエンコードに変換されてからプログラムに渡されます。 このデータが送り返されるときは、リトルエンディアンエンコードに戻されます。
論理条件基準では、Unicode のオペランドを英数字およびバイナリのオペランドとともに使用できます。 すべてのオペランドが Unicode のオペランド(フォーマット U)というわけではない場合は、2 番目以降のオペランドはすべて最初のオペランドのフォーマットに変換されます。 バイナリのオペランド(フォーマット B)が 2 番目以降のオペランドとして指定された場合、バイナリのオペランドの長さは偶数である必要があります。バイナリのオペランドには Unicode コードポイントが含まれていると想定されます。
最初のオペランドが Unicode のオペランド(フォーマット U)であるために、比較が Unicode 比較として実行される場合、ICU 照合アルゴリズムが使用されます。 ICU アルゴリズムでは、単純なバイナリ比較は実行されません。 そのため、例えば次のような結果になります。
"U+0000" などの一部のコードポイントは、比較プロセスで無視されます。
組み合わされた文字は、等価の 1 つのコードポイントと等しいとみなされます。例えば、"U+00E4" によって表されるドイツ語の文字 "ä" と、コードポイント "U+0061" および "U+0308" の組み合わせは、ICU によって等しいとみなされます。
注意:
英数字と Unicode のオペランドの比較は、フィールドのシーケンスに応じて、異なる結果となる場合があります。
『プログラミングガイド』の「論理条件基準」も参照してください。
このセクションでは、次のトピックについて説明します。
システム変数 *CODEPAGE
は、デフォルトコードページ(Unicode とコードページフォーマット間の変換に使用されているコードページ)の IANA 名を返すために使用されます。
システム変数 *LOCALE
には、現在のロケールの言語および国が含まれています。
U フォーマットは、ラージ変数およびダイナミック変数に使用できます。 ダイナミック U 変数の場合、*LENGTH
によって UTF-16 コード単位の数が返されます。
『プログラミングガイド』の「ダイナミック変数およびフィールドについて」も参照してください。
次のセッションパラメータを使用できます。
パラメータ | 説明 |
---|---|
DL |
フォーマット A または U のフィールドの表示長を指定します。 『プログラミングガイド』の「出力の表示長 - DL パラメータ」も参照してください。 |
EMU * |
Unicode での編集マスク |
ICU * |
Unicode での挿入文字 |
LCU * |
Unicode での先頭文字 |
TCU * |
Unicode での末尾文字 |
上記の表でアスタリスク(*)マークが付いたセッションパラメータは、Windows、UNIX、および OpenVMS プラットフォームでのみ使用できます。
DL
と AL
の比較
Natural が Unicode 対応ではなかった間は、英数字フィールドの長さは、フィールドを表示するために必要な列の数(表示列の数)と常に同じでした。 このことは、DBCS コードページを使用する東アジア言語についても該当しました。A フォーマットフィールドは、半分の文字のみを保持できます。例えば、A10 は A5 になります。
例:
DEFINE DATA LOCAL 1 #A8 (A8) END-DEFINE #A8 := 'computer' WRITE #A8 #A8 := '' WRITE #A8 END
上のコードの出力結果は、次のとおりです。
Page 1 ... computer
U フォーマットフィールドでは、フィールドの長さと表示列の数は同じではなくなります。 U の文字は、狭い幅(ラテン文字など)か、広い幅(中国語文字など)か、または幅を持たない(結合文字など)場合があります。 したがって、U フィールドが必要とする表示列の数はまったくわかりません。これは、フィールドの内容によって異なります。
Natural では、画面上に予約する必要がある列の数を自動的に決定できません。最大サイズを想定するとラテン出力で大きな差異が発生し、最小サイズを想定すると中国語出力が完全には表示されない場合があります。 したがって、Natural のプログラマは、フィールドの表示幅を定義する必要があります。これは、DL
パラメータを使用して行います。 AL
パラメータは、この目的には使用できません。このパラメータでは、フィールドの定義された長さを超える部分が切り取られるためです。 U フィールドから文字を切り取るのではなく、次のフィールドの開始位置のみを定義する必要があります。
例:
DEFINE DATA LOCAL 1 #U8 (U8) 1 #U4 (U4) END-DEFINE #U8 := 'computer' WRITE #U8 #U4 := U'' WRITE #U4 (DL=8) END
上記のコードの結果は、前と同じ出力になります。
Page 1 ... computer
Windows では、出力ウィンドウを使用してローカルで、または Natural Web I/O インターフェイスクライアントを使用してリモート開発環境で、DL
パラメータに定義された値がフィールドの実際の表示幅よりも小さいフィールド内をスクロールできます。
EMU
、ICU
、LCU
、TCU
と EM
、IC
、LC
、TC
の比較
パラメータ EMU
、ICU
、LCU
、および TCU
(Windows、UNIX、および OpenVMS プラットフォームでのみ使用可能)を使用すると、デフォルトコードページに含まれていない文字を使用できます。 文字は、生成されたプログラムに Unicode フォーマットで保存されます。 これらのパラメータは、すべてのフィールドフォーマットで使用できます。
パラメータ EM
、IC
、LC
、および TC
も、U フォーマットフィールドで使用できます。 デフォルトコードページに含まれている文字が他のコードページではエンコードが異なる場合に、これらのパラメータも便利な場合があります。 例えば、ユーロ記号(€)は、"windows-1252"(Latin 1)コードページではコードポイント "0x80" ですが、"windows-1251"(キリル語)コードページではコードポイント "0x88" です。 したがって、Unicode パラメータを使用することによって、PC にインストールされているコードページにかかわらず、ユーロ記号は常に正しく表示されるようになります。
EMU
の例:
DEFINE DATA LOCAL 01 EMPLOYEES-VIEW VIEW OF EMPLOYEES 02 FIRST-NAME 02 NAME 02 SALARY (1) END-DEFINE * READ (6) EMPLOYEES-VIEW DISPLAY NAME FIRST-NAME SALARY(1) (EMU=999,999) END-READ * END
上のコードの出力結果は、次のとおりです。
Page 1 05-12-15 11:45:36 NAME FIRST-NAME ANNUAL SALARY -------------------- -------------------- -------- ADAM SIMONE 159,980 MORENO HUMBERTO 165,810 BLOND ALEXANDRE 172,000 MAIZIERE ELISABETH 166,900 CAOUDAL ALBERT 167,350 VERDIE BERNARD 170,100
ライブラリ SYSEXPG
に、Natural での Unicode およびコードページのサポートのサンプルプログラムがあります。
UNICOX01
は、すべての Unicode 文字をリストします。
UNICOX02
は、Unicode 文字をコードポイントに、またはその逆に変換します。
CODEPX01
は、すべてのコードページ、そのコードページが Natural でサポートされているかどうか、およびそのコードページが使用するエンコードをリストします。 サポートされるすべてのコードページについて、そのコードページの文字をリストするサービスおよびコードページの文字列を
16 進表示に変換したり、その逆に変換したりするサービスを提供します。
CODEPXL1
は、任意の 1 バイトコードページのすべての文字をリストします。
CODEPXL2
は、任意の 2 バイトコードページのすべての文字をリストします。
CODEPXC1
は、任意のコードページの文字列を 16 進表示に、およびその逆に変換します。