この記事は最終更新から6年以上経過しています。内容が古くなっている可能性があります。
MySQL では以前から REGEXP
を使った正規表現をサポートしてきましたが、MySQL 8.0 からは Henry Spencer regular expression library から ICU (International Components for Unicode のライブラリに変わりました。これによってユニコードがサポートされ、マルチバイトセーフになりました。
- MySQL :: MySQL 8.0 Reference Manual :: 1.4 What Is New in MySQL 8.0
- MySQL :: WL#353: Better REGEXP package
- MySQL Bugs: #30241: Regular expression problems
目次
検証
まずは MySQL 5.7 で文字コード設定を utf8mb4 にします
1 2 3 4 5 |
[client] default-character-set = utf8mb4 [mysqld] character_set_server = utf8mb4 |
MySQLの再起動後、文字コードと照合順序を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
mysql> show variables like 'character\_set\_%'; +--------------------------+---------+ | Variable_name | Value | +--------------------------+---------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | +--------------------------+---------+ 7 rows in set (0.00 sec) mysql> show variables like 'coll%'; +----------------------+--------------------+ | Variable_name | Value | +----------------------+--------------------+ | collation_connection | utf8mb4_general_ci | | collation_database | utf8mb4_general_ci | | collation_server | utf8mb4_general_ci | +----------------------+--------------------+ 3 rows in set (0.00 sec) |
下記のバグレポートではおそらくロシア語による正規表現で問題が発生していますが、日本語で同様の REGEXP による検索をしてみたいと思います。
MySQL :: WL#353: Better REGEXP package
"^[^ん]"
の正規表現は “先頭文字が「ん」を含まない場合にマッチする” です。
なので期待する結果は 1 ですが、マッチせず 0 となっています。
1 2 3 4 5 6 7 |
mysql> select "あいうえお" regexp "^[^ん]"; +------------------------------------+ | "あいうえお" regexp "^[^ん]" | +------------------------------------+ | 0 | +------------------------------------+ 1 row in set (0.00 sec) |
MySQL 8.0 の場合の結果は以下のように期待通りの結果となりました。
1 2 3 4 5 6 7 |
mysql> select "あいうえお" regexp "^[^ん]"; +------------------------------------+ | "あいうえお" regexp "^[^ん]" | +------------------------------------+ | 1 | +------------------------------------+ 1 row in set (0.00 sec) |
まとめ
MySQLの正規表現はマルチバイトセーフではなかったため、今まであまり使われてこなかったと思いますが、MySQL 8.0 からは正しく動作するようになったので今後は広く使われるようになると思います。