正規表現を簡単に作るには
Sunday, September 13, 2015 04:11:00 PM
皆さんは正規表現好きですか?そして得意ですか? 私は好きですが、得意とは言えません。
VerbalExpressionという選択肢
そこでVervalExpressionという正規表現を簡単に組むことができる仕組みがあります。
http://verbalexpressions.github.io/
サイトに「Regular Expressions made easy」と書いてあるように、簡単に正規表現が作れることを表明しています。 様々な言語にポートされていますが、もちろんPHP版もあります。
https://github.com/VerbalExpressions/PHPVerbalExpressions
サイトのサンプルにも書いてあるとおり、以下のようなURLにマッチする正規表現が記述できます。
use VerbalExpressions\PHPVerbalExpressions\VerbalExpressions;
$regex = new VerbalExpressions;
$regex ->startOfLine()
->then("http")
->maybe("s")
->then("://")
->maybe("www.")
->anythingBut(" ")
->endOfLine();
echo $regex->getRegex() ."\n";
if (preg_match($regex, 'http://github.com')) {
echo "valid url\n";
} else {
echo "invalud url\n";
}
1つ目のechoの結果は /^(?:http)(?:s)?(?:\:\/\/)(?:www\.)?(?:[^ ]*)$/m
で、2つ目のechoは valid url
を表示します。
VerbalExpressionsクラスに toString
メソッドが実装されているので、 preg_match
関数でそのまま使えます。
複雑なことはできるか?
例えばRFC3986に書いてあるURLパターンをマッチさせようとすると、どうなるでしょうか? 一旦スキーマ部分だけ記述してみます。
$rfc3986 = new VerbalExpressions;
// scheme
$scheme = new VerbalExpressions;
$scheme->add("http")->maybe("s")->_or("ftp");
$rfc3986->startOfLine()
->add($scheme)
->add("://");
echo $rfc3986->getRegex() ."\n";
結果は /^(?:\(\?\:http\)\(\?\:s\)\?\)\|\(\?\:ftp)(?:\:\/\/)/m
のようになってしまい、期待通りではありません。
この実装は入れ子には対応していないようです。
もう1つのVerbalExpression実装
PHPにはもう1つ別のVerbalExpression実装があります。
https://github.com/markwilson/VerbalExpressionsPhp
こちらの実装はREADMEに入れ子について記述されているように、入れ子の対応はされているようです。 では早速RFC3986の定義を試してみましょう。
$rfc3986 = new VerbalExpression;
// scheme
$scheme = new VerbalExpression;
$scheme->then("http", false)->maybe("s", false)->orPipe("ftp", false);
$rfc3986->startOfLine()
->find($scheme)
->find("://")
->endOfLine();
echo $rfc3986->compile() ."\n";
結果は ^((?:http)(?:s)?()|()(ftp))(\:\/\/)$
のようになってしまい、まぁ不正ではないのですが、かなり無駄があります。
現時点結局のところ
どちらの実装も簡単なパターンをやるときには良いのですが、ちょっと複雑なパターンを実装しようと思うと微妙です。 大体、簡単なパターンはそのまま正規表現書けば良いじゃん… という話ですしね。
目指したいところ
RubyのVerbalExpressions実装には HEXPRESS があります。
これはVerbalExpressionsよりさらに便利なヘルパーを備えて Human Expressions, a human way to define regular expressions
という標語のとおりより簡単に実装できるように見えます。
これをPHPに移植して使えるようにしようというのが、直近やろうとしていることです。
さいごに
日本PHPカンファレンス2015が10/3(土)に行われます。 私もスピーカーとして登壇しますので、もしご都合がつく方はよろしくお願いします。
Recent Articles
- マルチプルレポをモノレポへコミットログを残しながら移行する 2023/09/27
- tsyringe を TypeScript 5 で使う方法 2023/05/02
- LocalStack を使って aws-sdk の Integration Test を実行する 2023/04/19
- AWS SDK v3 のモジュールと利用方法 2023/04/18
- ts-jest が esbuild/swc をトランスフォーマーに使って高速化していた 2023/04/13
- aws-sdk v3 を使うライブラリを作ったときは、なるべく peerDependencies に設定しよう 2023/04/11
- aws-sdk v2 が 2023 年中にメンテナンスモードになる 2023/04/06
- Node.js v18 / aws-sdk v3 の Lambda アプリが突然動かなくなる 2023/04/05
- aws-sdk v3 でコンパイルエラーになる - その2 2023/04/04
- aws-sdk v3 で TS2345 が出てコンパイルエラーになる 2023/04/03