◆ 文字列内に区切り文字つけて正規表現関数でのみそれを正規表現として扱う
◆ IGNORECASE みたいなフラグがないときは文字列のクオートと区切り文字 2 つ必要でムダが多い
◆ 正規表現オブジェクトを用意したりリテラル用意したりのほうがよかった

久々に使うとやっぱり PHP の正規表現の書き方は特殊というか変です

リテラル

JavaScript や Ruby では専用の構文があり リテラルで書くことができます
また 正規表現オブジェクトのコンストラクタから作る方法もあります

/[a-z]/i

リテラルは JavaScript も Ruby も同じで 「/」 で囲んであとの方の「/」の後に大文字小文字無視などのフラグをつけます

Perl はあまり詳しくないのですが

=~ /[a-z]/i

のように =~ も含んで構文みたいです
「/」 を使うのは JavaScript と一緒ですが

m|[a-z]|i

のように m をつけると好きな区切り文字に置き換えることもできるようです

関数

JavaScript で関数(コンストラクタ)から正規表現オブジェクトを作る場合は

new RegExp("[a-z]", "i")

となります

C# も同じようにコンストラクタからオブジェクトを作ります

new Regex("[a-z]", RegexOptions.IgnoreCase)

Python は正規表現オブジェクトを作ることもできますし 関数によってはそのまま文字列で書くことも出来ます

re.compile("[a-z]", re.I)

正規表現オブジェクトを使わない場合

re.search("[a-z]", "text", re.I)

PHP

問題は PHP です
PHP には正規表現オブジェクトというのがなくて文字列で表現します

'/[a-z]/i'

フラグ部分がなくても区切り文字が必要です

'/[a-z]/'

すごくムダな感じがしますし フラグないときは区切り文字を忘れがちです
もう正規表現リテラルにしてよって思います

Perl のように 区切り文字は変更できます

'@[a-z]@'
'#[a-z]#'

こういうのでもおっけいです
個人的には Shift キーと数字キーの組み合わせで入力する記号は打ちづらいので 「/」 か 「@」 です
URL や パスだと 「/」 が入るので 「@」 を使うことのほうが多いかもです

Perl だとまだリテラルだったのですが PHP だとただの文字列です
正規表現系関数以外に渡せば文字列として処理され 正規表現系関数に渡せば 区切り文字があれば正規表現として処理されます

いっそのこと正規表現オブジェクトを作ればよかったのに と思うのですが ユーザが正規表現を区切り文字とフラグつきで入力して処理することを考えていたりするのでしょうか
そういう使い方なら便利かもですが PHP コードを書く側からすると使いづらいだけの仕組みになってると思います

ただでさえ使いづらいところだらけなので大したものではないかもですけどね

正規表現の match の結果の取得でさえ

if(preg_match('@[a-z]@i', 'A', $matches)){
var_dump($matches);
} else {
echo 'NOT matched';
}

こんな面倒な形になります
C# の TryParse に近いです
参照を渡して返り値を入れてもらう って仕組みは C 時代の一つの値しか返せないから仕方なくってもので個人的にはなくなればいいのにって思うものです


リテラルないところと関数の使い勝手の悪さがあるので 入出力をわかりやすくするようラップするだけの正規表現クラスを作っておいたほうが楽 なのかもしれません

使うイメージはこんなの
$re = new RegExp('[a-z]', 'i');
$matched = $re->isMatch('A');
var_dump($matched);

$matches = $re->match('A');
var_dump($matches);

echo replace('text', $re, '.');

regexp と regex

ところで 複数の言語使ってるとどっちだったかわからなくなるのが regexp の p がいるかいらないかです

今回挙げた言語だと

regexp なのは

  • JavaScript
  • Ruby

regex なのは

  • C#

Python と Perl はコード中では特にどちらも使うことがないようです

Python は re モジュールで compile したものが regex のようですが あくまでドキュメント上の表記で regex という文字をプログラム中では使わないようです
つかうのは 「re」 というモジュール名です

Perl はドキュメントには regex も regexp もありましたがコードでは $REGERROR というのがあるくらいで regexp regex というのはプログラム中では使わないようです