UTF-8エンコーディングとPHPのstrlen()を想定すると、この文字列の長さが4になる可能性はありますか?
Strlen()について知りたいだけで、他の関数については知りません
これは文字列です:
$1�2
自分のコンピューターでテストし、UTF-8エンコーディングを検証しましたが、答えは6です。
Strlenのマニュアルや、UTF-8で読んだもので、上記の文字の一部が1未満と見なされる理由を説明するものは何もありません。
PS:この質問と回答(4)は、Ebayで購入したZCEの模擬テストからのものです。
投稿した文字列の長さは6文字です:$1�2(ドル記号、数字1、分音記号付きの小文字のi、逆さまの疑問符、半分の分数、数字2)
その文字列のUTF-8表現でstrlen()が呼び出された場合、結果は9になります(おそらく、長さが異なる複数の表現があります)。
ただし、その文字列をISO 8859-1またはCP1252として格納する場合、UTF-8として有効な6バイトの長さのシーケンスがあります。これらの6バイトをUTF-8として再解釈すると、4文字になります:$ 1.2(ドル記号、1桁目、Unicode置換文字、2桁目)。つまり、単一文字「�」のUTF-8エンコーディングは、3文字「�」のISO-8859-1エンコーディングと同じです。
置換文字は、UTF-8デコーダーが有効なUTF-8データではないデータを読み取るときに挿入されることがよくあります。
元の文字列は、複数の誤解の層を介して処理されたようです。非UTF-8データでUTF-8デコーダーを使用して($ 1.2を生成)、次にそのデータを分析するために使用したものを使用して($1�2を生成)。
mb_strlen()を使用するのはどうですか?
http://lt.php.net/manual/en/function.mb-strlen.php
ただし、strlenを使用する必要がある場合は、mbstring.func_overloadディレクティブを2に設定することでウェブサーバーを構成できるため、スクリプトでのstrlenの使用がmb_strlenに自動的に置き換えられます。
マルチバイト文字列関数を使用する必要があります mb_strlen() 次のようになります。
mb_strlen($string, 'UTF-8');
質問の準備からそれを読むまでのある時点で、いくつかのプロセスが非ASCII文字を壊してしまった可能性があります。そのため、質問は元々4文字の文字列に関するものでした。
シーケンス�
は、UTF-8で 置換文字U + FFFD (�)をエンコードし、その結果をlatin1で解釈すると取得されます。この文字は、たとえば、ファイルからテキストを読み取るときに文字をエンコードしないバイトシーケンスの代わりに使用されます。起こったことはおそらくこれです:
Latin1テキストファイルに保存された元の質問には、次のものが含まれていました:$1¢2
(¢は任意の非ASCII文字に置き換えることができます)
このファイルは、UTF-8を使用するプログラムによって読み取られました。 ¢に対応するバイトを解釈できなかったため、プログラムはそれを置き換えて、テキスト$1�2
を読み取りました。次に、このテキストはUTF-8を使用して書き出され、ファイルに$1\xEF\xBF\xBD2
が作成されました。
次に、latin1のファイルを読み取り、$1�2
を表示する3番目のプログラムが登場します。
番号。
矛盾による証明を使用します。
strlenはバイトをカウントするため、strlenが4の場合、その文字列には正確に4バイトが含まれている必要があります。
UTF8エンコーディングには文字あたり少なくとも1バイトが必要です。
私たちはそれを確立しました:
...まだ、6文字あります...これは矛盾しています。だから、いや。
ただし、完全に明確ではないのは、表示ソフトウェア(Webブラウザなど)が文字列を解釈するために使用している文字セットです。文字を8ビット未満で表すことができるいくつかの珍しいエンコーディングスキームを使用することができます。この場合、4バイトは6文字として表示される可能性があります。したがって、文字列はutf8である可能性がありますが、ブラウザはそれを、たとえば5ビットの文字セットとして解釈することを決定できます。
多くのUTF-8文字は、1バイトではなく数バイトを使用します。これがUTF-8の構築方法です(これにより、1つのセットに非常に多くの文字を含めることができます)。
代わりにmb_strlen()
を試してください。