#!/usr/bin/env perl use v5.12; use warnings; $_ = 123456789; s/ (?<=[0-9]) # 前に1文字以上の数字があり (?=(?:[0-9]{3})+ # 後ろに3文字の数字のセットが1個以上あり $) # 後ろに余計なものが続かない位置にマッチ /,/gx; # マッチした位置にカンマを挿入 say; # 123,456,789 $_ = 12345678; s/(?<=[0-9])(?=(?:[0-9]{3})+$)/,/g; say; # 12,345,678上記正規表現は、『詳説 正規表現 第3版』p.62より
タグ:正規表現
[正規表現] 分岐は遅い
正規表現では、「分岐」は遅いです。「a又はb又はcのいずれかにマッチ」する正規表現であれば、(a|b|c)よりも、[abc]の方が確実に速いです。
このことは、PHPマニュアルにも記載されています。
実際にどのくらいの差があるのか、見てみましょう。
(ベンチマーク用の正規表現は、404 Blog Not Found:perl - 自動で /a|b|c/ を /[abc]/ にしてくれたら...を参考にしました)
ただし、言語によっては、正規表現エンジンが正規表現の最適化を行ってくれます。実際、Ruby 2.0.0で上記例と同様の正規表現を実行すると、ほとんど差がありません。
残念ながら、PHPでは今のところ正規表現の最適化は自動で行われません。手動で最適化を行う必要があります。
PerlのRegexp::AssembleのPHP移植版もあるみたいなので、この辺使うと良いかも。
このことは、PHPマニュアルにも記載されています。
実際にどのくらいの差があるのか、見てみましょう。
(ベンチマーク用の正規表現は、404 Blog Not Found:perl - 自動で /a|b|c/ を /[abc]/ にしてくれたら...を参考にしました)
<?php $re_alt = '/s|t|u|v|w|x|y|z/'; $re_cclass = '/[stuvwxyz]/'; $alphabets = 'abcdefghijklmnopqrstuvwxyz'; $ntimes = 100000; $start = microtime(true) * 1000; for ($i = $ntimes; $i > 0; $i--) { preg_match($re_alt, $alphabets); } $end = microtime(true) * 1000; var_dump($end - $start); // 分岐:約0.30秒 $start = microtime(true) * 1000; for ($i = $ntimes; $i > 0; $i--) { preg_match($re_cclass, $alphabets); } $end = microtime(true) * 1000; var_dump($end - $start); // 文字クラス:約0.14秒PHP Sandboxで実際に実行できますが、実行時間には2倍〜3倍程度の差がつきます。
ただし、言語によっては、正規表現エンジンが正規表現の最適化を行ってくれます。実際、Ruby 2.0.0で上記例と同様の正規表現を実行すると、ほとんど差がありません。
残念ながら、PHPでは今のところ正規表現の最適化は自動で行われません。手動で最適化を行う必要があります。
PerlのRegexp::AssembleのPHP移植版もあるみたいなので、この辺使うと良いかも。
7月のまとめと8月の展望
7月は、SQLやRDBの設計等について学習しました。
読んだのは、『Head First SQL』。
RDBのテーブルの正規化についてきちんと学べたのは良かったです。
ただ、月の後半から新しいタスクが発生し、そちらでMongoDBが必要になったため、月の後半はMongoDBの学習が中心でした。
MongoDBは、NoSQLデータベースの一つで、ドキュメント指向データベースと呼ばれます。スキーマレス、すなわち、事前に入力するデータの形式を指定しない点に特徴があります。
実際使ってみると、RDBにはない手軽さがある反面、綴りの違いがそのまま別データとして格納されるといった怖い側面もあります(例えば、languageとlang)。
RDBと比較した際、明らかな欠点は、ライブラリが未成熟な点。私が現在担当しているプロダクトではActiveMongoライブラリを使っていますが、ドキュメントがほとんど無い上に、実装のおかしな箇所もあったりするので、生のMongoDBドライバを使わざるをえない場面があります。また、フレームワークのページャーが利用できなくて、自分でページャーを書いたり。。。
-----
8月は、『詳説 正規表現 第3版』を読もうと思います(現在読んでるところ)。
詳説 正規表現 第3版 [大型本]
堅いタイトル・オライリーブランド・分厚さ と、読者を怖気づかせる要素に事欠きませんが、実際読んでみると非常に読みやすい。全くの初心者にも伝わるように、正規表現の考え方から説き起こしています。
『詳説 正規表現』の後は未定。jQueryでもやろうかなと思います。
読んだのは、『Head First SQL』。
RDBのテーブルの正規化についてきちんと学べたのは良かったです。
ただ、月の後半から新しいタスクが発生し、そちらでMongoDBが必要になったため、月の後半はMongoDBの学習が中心でした。
MongoDBは、NoSQLデータベースの一つで、ドキュメント指向データベースと呼ばれます。スキーマレス、すなわち、事前に入力するデータの形式を指定しない点に特徴があります。
実際使ってみると、RDBにはない手軽さがある反面、綴りの違いがそのまま別データとして格納されるといった怖い側面もあります(例えば、languageとlang)。
RDBと比較した際、明らかな欠点は、ライブラリが未成熟な点。私が現在担当しているプロダクトではActiveMongoライブラリを使っていますが、ドキュメントがほとんど無い上に、実装のおかしな箇所もあったりするので、生のMongoDBドライバを使わざるをえない場面があります。また、フレームワークのページャーが利用できなくて、自分でページャーを書いたり。。。
-----
8月は、『詳説 正規表現 第3版』を読もうと思います(現在読んでるところ)。
詳説 正規表現 第3版 [大型本]
堅いタイトル・オライリーブランド・分厚さ と、読者を怖気づかせる要素に事欠きませんが、実際読んでみると非常に読みやすい。全くの初心者にも伝わるように、正規表現の考え方から説き起こしています。
『詳説 正規表現』の後は未定。jQueryでもやろうかなと思います。