5642


お世話になります。

phpのpreg系関数で正規表現パターンを以下のように記述する際に、検索対象文字列をシングルバイトのみの対象にする装飾子があった気がするのですが、ド忘れしてしまいました。

[code]

    preg_match("/^[0-9a-z\.\_\-]+$/",$str,$matched);
    
[/code]

これを

[code]

    preg_match("/^[:@0-9a-z\.\_\-]+$/",$str,$matched);
    
[/code]

のようにすれば、マルチバイト文字を検索することがないので  
正規表現検索が高速化出来た気がするのですが、ググってもそれらしきリソースが出てきませんでした。  
(私の検索方法が悪いのかもしれないのでしょうが)

皆様のお知恵をお貸しいただけませんでしょうか、宜しくお願い申し上げます。


CC BY-SA 3.0
2015-01-30T03:32:34.273
5600
2015-01-30T23:01:53.033
2015-01-30T11:27:42.003
49
question
php 正規表現
PCRE正規表現での文字列検索パターン高速化について


[パターン修飾子](http://php.net/manual/ja/reference.pcre.pattern.modifiers.php)のマニュアルをご覧いただければわかるように、UTF-8
を対象とする u (PCRE_UTF8) 修飾子は存在しますが、シングルバイトのモードは存在しません。u
オプションは後付けなので、デフォルトでシングルバイトモードとも言えます。ご提示の文字クラスを満たすかどうかをチェックする処理を C
言語のように書くと次のようになります。C
言語では1バイト単位で処理することになるので、それ以上の最適化を求めるのであれば、機械語の話になるのではないでしょうか。

[code]

    var_dump(
        true === is_allowed('aiueo12345._-'),
        false === is_allowed('あいうえお')
    );
    
    function is_allowed($str)
    {
        $size = strlen($str);
    
        for ($i = 0; $i < $size; ++$i) {
            $c = ord($str[$i]);
    
            if (($c >= 0x30 && 0x39 >= $c)
             || ($c >= 0x61 && 0x7a >= $c)
             || $c === 0x2d || $c === 0x2e || $c === 0x5f) {
                continue;
            }
    
            return false;
        }
    
        return true;
    }
    
[/code]

u オプションなしで UTF-8 の文字列を扱う際に注意する必要があることは誤検出や破壊してしまわないように配慮することです。PCRE
で定義されるエスケープシーケンスの `\h` (水平方向の空白文字)、`\s` (空白文字)、`\v` (垂直方向の空白文字)
が誤検出してしまうことが確認されています。くわしい情報は[こちらの記事](http://qiita.com/masakielastic/items/c44058dd42cece783c4f)をご参照ください。対策方法として挙げられるのは、必要に応じて、UTF-8
で定義されるすべての文字でテストすることです。誤検出や破壊の原因になっている正規表現を突き止めるには、UTF-8
の文字を構成する先行バイトと後続バイトの範囲の知識も必要になることもあるでしょう。


CC BY-SA 3.0
2015-01-30T22:22:43.143
5642
2015-01-30T23:01:53.033
2015-01-30T23:01:53.033
568
568
5600
answer