ホームページ >Java >&#&チュートリアル >留意すべきエッジケース。パートテキスト
あなたがソフトウェア開発者であっても、コピーライターであっても、あるいは単に電子メールを書いているだけであっても、テキストには注意しなければならない落とし穴がたくさんあります。アプリのバグから視覚的なアーティファクト、さらには被害者に至るまで、さまざまな問題を引き起こす可能性があります。それらを回避する方法を見てみましょう。
テキスト (別名文字列) は、プログラミング言語やプラットフォームなどに関係なく、hello-worlds のようなワンライナーから数十億行のコードを含むエンタープライズ システムに至るまで、事実上すべてのソフトウェア プロジェクトに存在します。テキストは単なる文字の連続ですから、これはロケット科学ではありませんよね?どのような罠に遭遇するか見てみましょう!
世界のアルファベットの一部 (英語を含む) は二院制であり、大文字と小文字の両方が含まれています。
たとえば、a は小文字、A は大文字です。ある大文字と小文字を別の文字に変換することは、非常に一般的な操作です。
大文字と小文字の区別は簡単なことのように思えるかもしれません。ある文字が別の文字に変換 (マッピング) されているだけです。 1 や + などの文字でなくても、それ自体が文字である場合もあります。さらに、このマッピングはいつでも簡単に反転できます。 A->a および a->A。したがって、一見するとすべてが順調に見えます。まあ、これほど真実からかけ離れたものはありません!
これは冗談ではなく、激怒したナチスの文法について話しているわけでもありません。この記事にあるように、筐体の不具合により 2 人の犠牲者が発生し、さらに 3 人が刑務所に入れられました。
どうしてそうなったのですか?トルコ語 (およびアゼルバイジャン語) には、点線 (閉じた) と点なし (開いた) という 2 つの異なる i 文字があります。英語およびその他のラテン文字では、小文字には常にドットが付きますが、大文字にはドットがありません。すべては表 1 とオンライン デモに示されています。
表 1. ドット付きおよびドットなしの i 文字。
Lowercase | Uppercase | |
---|---|---|
English | i dotted | I dotless |
Turkish | i dotted | İ dotted |
Turkish | ı dotless | I dotless |
ご覧のとおり、大文字と小文字の変更結果はコンテキストに依存し、さらに現在の言語に依存します。人間向けの文章を作成するときは、適切な言語を使用することが重要です。これを無視すると、あなたの言葉が意図とは異なる意味になってしまう可能性があります。
一方、HTTP ヘッダーや JSON キーなどの機械可読テキストは、言語に依存しない方法で処理される必要があります。そうしないと、出力に非 ASCII 文字が表示され、アプリケーション ロジックが破損する可能性があります。まさにその状況が、数千 (おそらく数百万) のプロジェクトで使用されるライブラリである GSON で発生しました。
発音記号を含む文字は、ó のように事前に合成することも、ó のように記号を組み合わせて作成することもできます。このページを読むと、どちらも同じキャラクターに見えます。しかし、2 番目の 16 進ダンプを見るか、このデモのようにプログラムでその長さを取得しようとすると、それが 2 つの個別の文字で構成されていることがわかります: ラテン語の小文字 o とアキュートアクセントの組み合わせです。同様に、各ハングル (韓国語のアルファベット) 音節ブロックは、事前に構成することも、個別の jamos の個々の文字の組み合わせとして記述することもできます。
なぜマークを組み合わせることがそれほど重要なのでしょうか?そうですね、発音記号を使用してほとんどの文字を書くには 2 つの方法があります (たとえば、ポーランド語、ハンガリー語、またはチェコ語のアルファベットから)。これにより、並べ替え、検索、テキストの長さの測定などの操作が重要になります。通常、最高のユーザー エクスペリエンスを実現するには、テキストを正規化する (通常の形式の 1 つに変換する) 必要があります。そうしないと、たとえば、同じように見える複数の「異なる」ログイン名やファイル名を見たときにユーザーが混乱する可能性があります。この好例は、Slack がチャネル名を処理する方法です。これらはチャンネル作成前に正規化されるため、同じ名前を異なる方法で記述した状況は共存できません。
キャラクターの同等性には 2 つのレベルがあります。 正規等価性 は、文字の意味と外観の両方が同じであると想定される場合に発生します。前述の ó と ó は、(技術的な) 書き方が異なるだけです。一方、互換性 は、文字が異なって見えるが、意味は同じである可能性があることを意味します。たとえば、合字 は 3 つの異なる文字 ffi と互換性がありますが、これらは標準的に同等ではありません。 Unicode 正規化の詳細については、標準ドキュメントを参照してください。
各 2 レベルの合成形式と分解形式の両方が標準化されているため、合計 4 つの正規形式がありますが、正規化は常に可逆であるとは限りません。たとえば、オングストローム記号 Å は、ラテン大文字 A A と ̊ の上の環を組み合わせたものに分解され、元のオングストローム記号ではなく、Å の上に環をもつラテン大文字 A に再構成されます。
特定のテキストを共有するすべてのアプリケーションが同じ正規化方法を使用することも重要です。そうしないと、微妙なエラーが発生したり、サイレントなデータ損失が発生したりする可能性があります。各アプリケーションは、少なくとも個別に実行している場合には問題なく動作するため、このようなバグを発見するのは難しい場合があります。このような場合、アプリケーションは多くの場合「クラッシュ」せず、本来とは異なるデータを送受信するだけで、予期せぬ結果を引き起こします。そのような例の 1 つは、nettalk のこのバグです。
前述の活版印刷の合字は、互いに隣接すると見にくい特定の文字の見た目を改善するために使用されます。合字はソフトウェアによって個々の文字から自動的に生成されるため、ほとんどのユーザーは合字について心配する必要はありません。 TeX はデフォルトで合字を生成します。ただし、このようなツールの開発者は、場合によっては合字が不適切でエラーが発生する可能性があることを考慮する必要があります。
これを見てください: . 2 番目の文字は点付きですか、それとも点なしですか?トルコ語を話す読者は混乱するかもしれません。 i を含む合字は、一部のコンテキストでは使用しないでください。
ラテン語やギリシャ語などのいくつかの文字 (いわゆる二院制) には 2 つの格の文字が含まれています。事実上すべての文字には小文字と大文字があります。事実上…しかし、絶対にすべてというわけではありません!
小文字セットは常に存在しますが、大文字には当てはまりません。では、小文字しかない文字がある場合、それを大文字に変換しようとするとどうなるでしょうか?操作が失敗する原因となるエラーでしょうか?性格はそのままでしょうか?答えはそんなものではありません!
最も顕著な例の 1 つは、ドイツ語のシャープ s — ß です。小文字ですが、大文字に変換するとダブルS~SSとなります。この変換は元に戻すことはできません。SS は ss になります。オンラインでご覧ください。 TL;DR Unicode 5.1 では ẞ (LATIN CAPITAL LETTER SHARP S) が導入されましたが、これは一般に文字マッピングの観点から ß の大文字とは見なされません。最近 (2016 年に) SS の同様に有効な形式としてドイツ語の正書法ルールセットに追加されました。
他の多くの小文字の合字には、対応する事前に作成された大文字の形式がありません。完全なリストは、Unicode Special Casing ドキュメントにあります。
一部の大文字が欠落していますが、何ですか?合字は 2 文字または 3 文字で構成される場合があるため、大文字のテキストは元の小文字の 3 倍の長さになる場合があります。これは、結果として得られるテキストの長さが制限されている場合には非常に重要です。たとえば、bitrise.io.
のこのバグのように、アバターやイニシャル ジェネレータで使用します。ギリシャ語のアルファベットには、大文字の Σ のようなシグマ文字が含まれています。小文字の形式は何ですか?まあ、それは状況次第です!通常は σ (非終端) ですが、語尾は ς (終端) になります。ただし、シグマが唯一の文字である場合、または単語がすべて大文字で書かれている場合は、最終位置であっても、常に非最終バージョンが使用されます。インタラクティブな例を参照してください。
ラテン大文字 i にチルダ Ĩ が付いた小文字は何ですか?ご想像のとおり、答えはそれほど簡単ではありません。対応する小文字形式が存在します。どちらのフォームもドットレスですが、まったく正常です。 i と j に発音記号が付いている場合、両方にドットは付きません。では、ここで何が問題なのでしょうか?
トルコ語とは別に、リトアニア語のオルトグラフィック規則は、I 文字の場合も例外的です。後者では、ドットはアクセントの下に保持されます。これは、たとえば、前述の Ĩ をリトアニア語の文脈で小文字にすると i̇̃ になることを意味します。よく見ると、ラテン語の小文字 i、その上の結合ドット、その上の結合チルダの 3 つの文字があることがわかります。テキストの長さが (再び) 3 倍に増加しました。
わずか6文字を使って、7文字からなる単語をどうやって書くことができますか?事前に作成された合字とマルチグラフ (2 文字、3 文字など) を使用するだけです。もちろん、結合された文字の可能な組み合わせごとに事前に作成された文字はありません。ただし、既存のものを使用して、テキストの長さの制限を効果的に増やすことができます。たとえば、シレジア語の dzbonek (鍋) は 7 文字で構成されますが、6 文字だけを使用して Ƴbonek と書くことができます。オンラインでご覧ください。 í は合字ではなく有向グラフであることに注意してください。
たとえば、140 文字を超えるメッセージをツイートできるようになりました。事前に作成された Unicode 二重グラフと合字のリストはここにあります。
アルファベット順は通常、小学校の初めに教えられます。 A、B、C、D…など、Z まで続きます。とても簡単です!
残念ながら、アルファベット順は言語によって異なります。基本的なラテン文字 (発音記号なし) の位置さえも異なる場合があります。たとえば、エストニア語では、文字 Z は S と T の間にあります。
発音区別符号が付いた文字の位置も普遍的ではありません。いくつかの可能なスキームがあります:
マルタ語のように、対応する基本文字の前: W、X、Ż、Z。
ポーランド語のように、対応する基本文字の後に: A、Ą、B、C、Ć。
スウェーデン語のようにアルファベットの末尾: Z、Å、Ä.
ハンガリー語のように、基本文字と同じ位置 (照合目的で): O=Ó.
同じ文字でもさまざまな言語で異なる照合が行われる場合があり、また、文脈によっては同じ言語でも異なる場合があることに注意してください。たとえば、スロバキア語では、ウムラウト付きの A は常に A の後に配置されます。ただし、ドイツ語では、ウムラウトなしのバージョンと同じ値を持つか、その後に配置されるか、A+E として扱われる場合もあります。どのような場合にどの方法が使用されるかについての詳細は、こちらをご覧ください。
照合の対象となるのは個々の文字だけではありません。マルチグラフには独自のルールを持たせることもできます。スロバキア語では、CH は H と I の間で照合されます。つまり、単語 chlieb (パン) は hodina (1 時間) の後に照合されます。一方、ポーランド語では、その二重グラフは 2 つの別々の文字 (C と H) のように扱われるため、特別な照合規則はありません。オンラインでご覧ください。
ハンガリー語には二重二重グラフもあり、それぞれに独自の照合ルールがあります。これにより、多くの複雑なケースが発生します。考えられる例を 1 つ考えてみましょう。 SZ ダイグラフがあります。 S の後に照合されます。その 2 倍のバージョン (SZ + SZ) が SSZ です。これは、kaszinó (カジノ) という単語が kassza (レジ) の前にある必要があることを意味します。通常、Z は S の後にありますが、ここでは、最初の単語に K A SZ I があり、2 番目の単語に (同等の) K A SZ SZ があります。
さらに、同じグループの文字が文脈に応じて (二重) ダイグラフになる場合もあれば、そうでない場合もあります。たとえば、前述のスロバキア語の CH は、一部の単語では C と H の 2 つの別々の文字として扱われます。 viachlas (ポリフォニー)。通常、ハンガリー語では、mennybolt (天国) という言葉のように、NNY = NY + NY です。ただし、tizennyolc (18) もあります。ここで、NNY = N + NY であるため、単一の文字 N と単一のダイグラフ NY が存在します。
上の見出しは単なるラテン文字だけで構成されていると思うかもしれません。実際、それらの大部分はギリシャ語、キリル文字、またはアルメニア語の大文字です。これらは一部のラテン文字の同形文字にすぎません。
つまり、A (ラテン大文字の A) は、Α (ギリシャ大文字のアルファ) や А (キリル大文字の A) と同じものではありません。これがなぜ重要なのでしょうか?これらは区別できないため、IDN ホモグラフ攻撃に使用される可能性があります。たとえば、ラテン文字のみを含むドメイン Bank.com は、ラテン文字の小さい A の代わりにキリル文字の小さい A を含む、bank.com とほぼ同じに見えます。このようなドメインはフィッシングに使用される可能性があります。
特に多言語環境で作業している場合、テキストの処理が難しい場合があります。経験則として、すべての構成は特定のコンテキストに適切である必要があります。たとえば、これらのユーザーに表示されるテキストを処理するときは、ユーザーの現在の言語を考慮する必要がありますが、機械可読テキストは言語に依存しない方法で処理される必要があります (不可能な場合は英語を使用します)。選択した照合設定は、実際の使用状況と一致する必要があります。テキストは必要に応じて正規化する必要があり、選択した正規化方法はシステム全体で一貫している必要があります。
さらに特殊なケースについて知りたいですか?パート 2 も準備中ですのでお楽しみに!
以上が留意すべきエッジケース。パートテキストの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。