-3

記載されていないエンコーディングの Unicode テキストを含むファイルがあります。このファイルをスキャンして、U+0600 から U+06FF までの範囲のアラビア語コード ポイントを探し、該当する各 Unicode コード ポイントを ASCII のバイトにマップして、新しく作成されたファイルが純粋な ASCII 文字で構成されるようにします。 、すべてのコード ポイントが 128 未満です。

どうすればこれを行うことができますか?ASCII と同じように読み取ろうとしましたが ??、マルチバイト文字であるため端末に表示されます。

: ファイルは Unicode 文字セットのサブセットで構成されており、サブセットのサイズは ASCII 文字のサイズよりも小さくなっています。したがって、この特定の Unicode サブセットから ASCII への 1:1 マッピングを行うことができます。

4

3 に答える 3

4

これは不可能であるか、些細なことです。ささいなアプローチは次のとおりです。

  • 127を超えるコードポイントがない場合は、ASCIIで書き出すだけです。終わり。

  • 一部のコードポイントが127を超える場合は、それらをASCIIで表す方法を選択する必要があります。α一般的な戦略は、U+03B1の場合のようにXML構文を使用することです。これには、文字起こしされるトランスASCIIUnicodeコードポイントごとに最大8つのASCII文字が必要です。

元のポスターの練習問題として残した不可能なもの。これらは軍団であるため、私は愚かであるが可能性のある(読む:愚かな)​​アプローチについても言及しません。データ破壊はデータ処理における資本犯罪であり、そのように扱われる必要があります。

「Unicode文字」とは、実際には「Unicodeコードポイント」を意味すると想定していることに注意してください。つまり、プログラマーに見える文字です。ユーザーに表示される文字の場合は、代わりに「Unicode書記素(クラスター)」が必要です。

また、最初にテキストを正規化しない限り、世界を憎むでしょう。NFDをお勧めします。


編集

元のポスターでさらに明確にした後、彼がやりたいことは、新しいプログラムを作成しなくても、既存のツールを使用して非常に簡単に達成できるようです。たとえば、これは特定のアラビア文字のセットをUTF-8入力ファイルからASCII出力ファイルに変換します。

$ perl -CSAD -Mutf8 -pe 'tr[ابتثجحخد][abttjhhd]' < input.utf8 > output.ascii

これらのコードポイントのみを処理します。

U+0627 ‭ ا  ARABIC LETTER ALEF
U+0628 ‭ ب  ARABIC LETTER BEH
U+0629 ‭ ة  ARABIC LETTER TEH MARBUTA
U+062A ‭ ت  ARABIC LETTER TEH
U+062B ‭ ث  ARABIC LETTER THEH
U+062C ‭ ج  ARABIC LETTER JEEM
U+062D ‭ ح  ARABIC LETTER HAH
U+062E ‭ خ  ARABIC LETTER KHAH
U+062F ‭ د  ARABIC LETTER DAL

したがって、必要なマッピングに拡張する必要があります。

コマンドラインツールではなくスクリプトで使用する場合も簡単です。さらに、次のようなマッピングを設定することで、名前でキャラクターについて話すことができます。

 "\N{ARABIC LETTER ALEF}"   =>  "a",
 "\N{ARABIC LETTER BEH}"    =>  "b",
 "\N{ARABIC LETTER TEH}"    =>  "t",
 "\N{ARABIC LETTER THEH}"   =>  "t",
 "\N{ARABIC LETTER JEEM}"   =>  "j",
 "\N{ARABIC LETTER HAH}"    =>  "h",
 "\N{ARABIC LETTER KHAH}"   =>  "h",
 "\N{ARABIC LETTER DAL}"    =>  "d",

これがより大きなC++プログラムのコンポーネントであると想定される場合は、おそらくこれをC ++で実装する必要がありますが、音訳サポートを含むICU4Cライブラリを使用する必要はありません。

しかし、必要なのが単純な変換だけである場合、専用のC++プログラムを作成する理由がわかりません。仕事が多すぎるようです。

于 2012-02-17T18:47:49.683 に答える
1

フォーマットを知らなければ、データを読み込むことはできません。Microsoft Word でファイルを開き、「名前を付けて保存」、「その他の形式」、「プレーン テキスト (.txt)」で保存します。変換ボックスで、「その他のエンコーディング」、「Unicode」(UTF16LE)、「OK」を選択します。そのファイルは現在、UTF16LE として保存されています。

std:ifstream infile("myfile.txt", std::ios::binary); //open stream
infile.seekg (0, ios::end); //get it's size
int length = infile.tellg();
infile.seekg (0, ios::beg);
std::wstring filetext(length/2); //allocate space
ifstream.read((char*)&filetext[0], length); //read entire file
std::string final(length/2);
for(int i=0; i<length/2; ++i) { //"shift" the variables to "valid" range
    if (filetext[length/2] >= 0x600 && filetext[length/2] <= 0xFF)
        final[length/2] = filetext[length/2]-0x600;
    else
        throw std::exception("INVALID CHARACTER");
}
//done

あらゆる警告: これがあなたの望む結果になるとはとても思えませんが、必要な翻訳やファイルのフォーマットを私たちに伝えていないので、これが管理できる最善の方法です. また、あなたのコンピューターとコンパイラーは私のものと同じだと思います。そうでない場合、これらの一部またはすべてが間違っている可能性がありますが、あなたが私たちに伝えていないこの不足している情報について私ができる最善のことです.

于 2012-02-17T19:16:04.230 に答える
0

Unicode コードポイントを解析するには、まずファイルをエンコードされていない Unicode 表現 (UTF-32 と同等) にデコードする必要があります。そのためには、まず、ファイルがどのようにエンコードされ、デコードできるようになったかを知る必要があります。たとえば、Unicode コードポイントは、UTF-8、UTF -16LE、UTF -16BEU+0600などでエンコードされます。U+06FF0xD8 0x800xDB 0xBF0x00 0x060xFF 0x060x06 0x000x06 0xFF

ファイルが BOM で始まる場合、使用されている正確なエンコーディングがわかっているため、それに応じてファイルの残りを解釈できます。たとえば、UTF-8 BOM は0xEF 0xBB 0xBF、UTF-16LE は0xFF 0xFE、UTF-16BE は0xFE 0xFFなどです。

ファイルが BOM で始まらない場合は、データを分析し、それに対してヒューリスティックスを実行してエンコーディングを検出する必要がありますが、これは 100% 信頼できるわけではありません。UTF エンコーディングを検出するのはかなり簡単ですが、Ansi エンコーディングを確実に検出することはほぼ不可能です。BOM が存在しない UTF エンコーディングを検出しても、誤った結果が生じることがあります (これこれ、およびこれを読んでください)。

推測しないでください。データが失われる危険があります。使用されている正確なエンコーディングがわからない場合は、ユーザーに問い合わせてください。

于 2012-02-18T02:18:43.000 に答える