2013-05-11 6 views
16

私はテーブルでutf8mb4エンコーディングをサポートしていないmysql 5.1サーバでutf8 charset mysqlテーブルを使用しています。 "","","","","","唧",""のような4バイトの符号化utf8文字を挿入するとき。表はエラーをポップアップするか、次のテキストをスキップします。phpは4バイトのコード化されたutf8文字を検出できますか?

PHPで4バイトのコード化されたutf8文字をプログラムで検出して置き換えるにはどうすればよいですか?

+0

非常にシンプルに:4' ==文字で(そうする多くの方法を)文字列を分割し、 'strlenを($ CHAR)かどうかを確認します。これが本当にMySQLが処理できない文字を検出する正しい方法であるかどうかはわかりませんが、コードポイントの方がより正確です。 – deceze

+0

[multibyte extension](http://php.net/mbstring)をチェックしましたか?また、必ず[コメントを読む](http://dk1.php.net/manual/en/function.mb-internal-encoding.php#66568)を必ず読んでください。 –

+0

@decezeそれがアプローチです。他に優雅なやり方がないなら、私はそれに行きます。 –

答えて

13

次の正規表現は、4バイトのUTF-8文字を置換します:

function replace4byte($string, $replacement = '') { 
    return preg_replace('%(?: 
      \xF0[\x90-\xBF][\x80-\xBF]{2}  # planes 1-3 
     | [\xF1-\xF3][\x80-\xBF]{3}   # planes 4-15 
     | \xF4[\x80-\x8F][\x80-\xBF]{2}  # plane 16 
    )%xs', $replacement, $string);  
} 

var_dump(replace4byte('d'), replace4byte('dd')); 

あなたはPCREがあることのためUTF-8を心配する必要はありませんので、これは、/u修飾に依存しませんあなたがそのサポートを持っているなら、decezeのpreg_replace_callbackはほんの少しです。

(正規表現がEnsuring valid utf-8 in PHPから適応)

13

これは動作するはず:

if (max(array_map('ord', str_split($string))) >= 240) 

を合理的であるそのコードポイントまでとU + FFFFを含む、フォーム1110xxxx 10xxxxxx 10xxxxxxの3バイトとして符号化されます。より高いコードポイントは、11110xxx 10xxxxxx 10xxxxxx 10xxxxxxの形式であり、すなわち、最高バイトは240以上の値を有する。文字列にこのようなバイトがある場合、それは4バイトシーケンスのインジケータです。あなたは長い文字を削除したい場合は

、これは行います:直接、高いコードポイントを表現するために、よりエレガントな正規表現の方法があるかもしれません

preg_replace_callback('/./u', function (array $match) { 
    return strlen($match[0]) >= 4 ? null : $match[0]; 
}, $string) 

けど。

+0

検出していただきありがとうございますが、置き換えの例もありますか? $ a = "私はテーブルに挿入できません、blahblahblah"; //ターゲット$ a == "omg、私のテーブルに、blahblahblahのMYTEXTを挿入できません"; –

関連する問題