Strings of Life

PHP/Phalcon/MySQL/JavaScript/RegExp/Ruby/Perl/ActionScript

タグ:正規表現

#!/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より

詳説 正規表現 第3版
Jeffrey E.F. Friedl
オライリージャパン
2008-04-26

正規表現では、「分岐」は遅いです。「a又はb又はcのいずれかにマッチ」する正規表現であれば、(a|b|c)よりも、[abc]の方が確実に速いです。

このことは、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月は、SQLやRDBの設計等について学習しました。

読んだのは、『Head First SQL』。

RDBのテーブルの正規化についてきちんと学べたのは良かったです。


ただ、月の後半から新しいタスクが発生し、そちらでMongoDBが必要になったため、月の後半はMongoDBの学習が中心でした。

MongoDBは、NoSQLデータベースの一つで、ドキュメント指向データベースと呼ばれます。スキーマレス、すなわち、事前に入力するデータの形式を指定しない点に特徴があります。

実際使ってみると、RDBにはない手軽さがある反面、綴りの違いがそのまま別データとして格納されるといった怖い側面もあります(例えば、languageとlang)。

RDBと比較した際、明らかな欠点は、ライブラリが未成熟な点。私が現在担当しているプロダクトではActiveMongoライブラリを使っていますが、ドキュメントがほとんど無い上に、実装のおかしな箇所もあったりするので、生のMongoDBドライバを使わざるをえない場面があります。また、フレームワークのページャーが利用できなくて、自分でページャーを書いたり。。。

-----

8月は、『詳説 正規表現 第3版』を読もうと思います(現在読んでるところ)。

詳説 正規表現 第3版
詳説 正規表現 第3版 [大型本]

堅いタイトル・オライリーブランド・分厚さ と、読者を怖気づかせる要素に事欠きませんが、実際読んでみると非常に読みやすい。全くの初心者にも伝わるように、正規表現の考え方から説き起こしています。

『詳説 正規表現』の後は未定。jQueryでもやろうかなと思います。

このページのトップヘ