59 votes

Compilation de regex en PHP

Existe-t-il un moyen en PHP de compiler une expression régulière, de sorte qu'elle puisse ensuite être comparée à plusieurs chaînes de caractères sans répéter le processus de compilation ? D'autres langages majeurs peuvent le faire -- Java, C#, Python, Javascript, etc.

42voto

Pat Leahy Points 1433

La bibliothèque d'expressions régulières compatible Perl a peut-être déjà été optimisée pour votre cas d'utilisation sans fournir une classe Regex comme le font d'autres langages :

Cette extension maintient un cache global par thread des expressions régulières compilées (jusqu'à 4096).

Introduction au PCRE

C'est ainsi que le modificateur d'étude qui Imran décrit peut stocker l'expression compilée entre les appels.

17voto

Imran Points 20117

Les regex preg peuvent utiliser le modificateur S (étude) en majuscules, ce qui est probablement ce que vous recherchez.

http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

S

Lorsqu'un modèle est destiné à être utilisé plusieurs fois, il vaut la peine de dépenser plus de temps à l'analyser afin d'accélérer accélérer le temps de correspondance. Si ce modificateur est activé, alors cette analyse supplémentaire est effectuée. A Actuellement, l'étude d'un motif n'est utile seulement pour les motifs non ancrés qui n'ont qui n'ont pas de caractère de départ fixe fixe de départ.

12voto

Mike Points 81

Thread est le thread dans lequel le script est actuellement exécuté. Après la première utilisation, la regexp compilée est mise en cache et la prochaine fois qu'elle est utilisée, PHP ne la compile pas à nouveau.

Un test simple :

<?php

function microtime_float() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

// test string
$text='The big brown <b>fox</b> jumped over a lazy <b>cat</b>';
$testTimes=10;

$avg=0;
for ($x=0; $x<$testTimes; $x++)
{
    $start=microtime_float();
    for ($i=0; $i<10000; $i++) {
        preg_match_all('/<b>(.*)<\/b>0?/', $text, $m);
    }
    $end=microtime_float();
    $avg += (float)$end-$start;
}

echo 'Regexp with caching avg '.($avg/$testTimes);

// regexp without caching
$avg=0;
for ($x=0; $x<$testTimes; $x++)
{
    $start=microtime_float();
    for ($i=0; $i<10000; $i++) {
        $pattern='/<b>(.*)<\/b>'.$i.'?/';
        preg_match_all($pattern, $text, $m);
    }
    $end=microtime_float();
    $avg += (float)$end-$start;
}

echo '<br/>Regexp without caching avg '.($avg/$testTimes);

Regexp avec mise en cache avg 0.1 Regexp sans cache avg 0.8

La mise en cache d'une regexp la rend 8 fois plus rapide !

7voto

1stvamp Points 51

Comme un autre commentateur l'a déjà dit, les regex PCRE sont déjà compilées sans que vous ayez à les référencer spécifiquement en tant que telles, PCRE conserve un hash interne indexé par la chaîne originale que vous avez fournie.

4voto

EBGreen Points 14478

Je ne suis pas sûr que vous puissiez le faire. Si vous regardez Maîtriser les expressions régulières Certaines techniques d'optimisation spécifiques à PHP sont abordées au chapitre 10 : PHP. En particulier, l'utilisation du modificateur de motif S pour que le moteur regex "étudie" l'expression régulière avant de l'appliquer. En fonction de votre motif et de votre texte, cela peut vous permettre de gagner en vitesse.

Modifier Vous pouvez jeter un coup d'œil au contenu du livre en utilisant le lien suivant livres.google.com .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X