波ダッシュと全角チルダの闇


正規表現で思うように処理してくれない事件勃発

私が業務で保守運用しているサービスにて特定のデータ反映がうまく行かないとの問い合わせが発生。
該当箇所のソースは以下。

if(preg_match('/^[0-9]{4}\/[0-9]{1,2}\/[0-9]{1,2} [0-9]{1,2}:[0-9]{2}/', $d[$val])) : 
// 2020/12/24 17:00:00

elseif(preg_match('/^[0-9]{2}\-[0-9]{2}\-[0-9]{2}$/', $d[$val])) : 
// 20-24-16

elseif(preg_match('/^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/', $d[$val])) : 
// 2020-12-24

elseif(preg_match('/^[0-9]{4}\/[0-9]{1,2}\/[0-9]{1,2}$/', $d[$val])) : 
// 2020/12/24

elseif(preg_match('/^[0-9]{2}\/[0-9]{2}\/[0-9]{2}  [0-9]{2}:[0-9]{2}/', $d[$val])) : 
// 12-24-20 17:00:00

elseif(preg_match('/^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2} [0-9]{1,2}:[0-9]{2}/', $d[$val])) : 
// 12/24/20 17:00:00

elseif(preg_match('/^([0-9]{1,2})月([0-9]{1,2})日((.+))([0-9]{1,2}:[0-9]{2})(.+)([0-9]{1,2}:[0-9]{2})$/', $d[$val], $matches)) : 
// 12月24日(日)17:00〜19:0
endif;

入力された日程データの形式で処理を行うという記述ですね。
おおよそ考えられうるすべての日程形式に対応できるよう記述しているつもりなのですがどれにも当てはまらず処理が行われていませんでした。
入力されていたデータを確認したところ最下段の判定に引っかかるような記述でした。
長時間頭を抱えたのですが結論から言うと「全角チルダとではなく波ダッシュを記載していた」というものでした。

ちょっと詳しく全角チルダと波ダッシュ

「~」と「〜」は実は全く違う文字らしいですね。
見た目がほとんど同じではあるんですが、内部的に持っている文字コード番号が違うようです。
波ダッシュ:U+301C
全角チルダ:U+FF5E
なので一見正規表現でヒットするはずであろう記述でも全角チルダと波ダッシュの違いでfalseと判定されてしまっていたようです。
Windowsで「から」と検索:~(←全角チルダ)
Macで「から」と検索:〜(←波ダッシュ)
まじで統一してくれ。。

終わりに

今回は波ダッシュを全角チルダに書き換えることにしましたが本来であれば両方に対応できるのが良いと思います。
疲れたマン