LoginSignup
4
3

More than 5 years have passed since last update.

MySQLの全角 ( マルチバイト ) 文字とREGEXP

Posted at

ハマったのでメモ。

結論

MySQLのREGEXPはマルチバイトには対応していないので気をつけないと駄目。

LIKEの場合

collationというものがある。

参考
https://www.slideshare.net/tmtm/mysql-2017
https://qiita.com/kazu56/items/6af85ffcf8d3954455ad

デフォルトではutf8_general_ci ( または utf8mb4_general_ci ) が設定されているらしい。
この場合、全角文字と半角文字は別の文字として判断される。

SELECT `users`.* FROM `users` WHERE (name like 'hoge')

=> "hoge", "Hoge"などはマッチするが、"hoge", "Hoge"などはマッチしない

全角半角区別なくマッチさせたかったので、collationをutf8_unicode_ciに無理やり変更することで対処。

参考
https://www.softel.co.jp/blogs/tech/archives/1877

SELECT `users`.* FROM `users` WHERE (name collate utf8_unicode_ci like 'hoge')

=> "hoge", "Hoge", "hoge", "Hoge", "hOgE"のいずれもマッチする。

やったぜ。

REGEXPの場合

検索したい文字列が1種類の場合、上記の手法で問題ない(はず)。
が、今回は複数文字列に対してマッチングさせたかった。
なのでRegEXPを利用することを考えたが、これでハマった。

SELECT `users`.* FROM `users` WHERE (name regexp 'hoge')

=> "hoge", "Hoge"はマッチする、"hoge", "Hoge"などはマッチしない

SELECT `users`.* FROM `users` WHERE (name collate utf8_unicode_ci regexp 'hoge')

=> "hoge", "Hoge"はマッチする、"hoge", "Hoge"などはマッチしない

調べたところ、MySQLはマルチバイト文字列に対するREGEXPには対応していないみたい。

https://dev.mysql.com/doc/refman/5.6/ja/regexp.html
https://stackoverflow.com/questions/39513264/mysql-regular-expression-for-multibyte-characters

公式ドキュメントはまず読んでみるべきだと反省。

LIKEORで頑張ろうと思うけど、そもそもレコードに保存する際に半角に変換するとかこんなクエリ考えないような設計にしたほうがいいのでは・・・?

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3