6
votes

Comment puis-je accélérer mon correspondance de Perl Regex?

Je veux capturer plusieurs textes en utilisant la regex suivante: xxx pré>

Un échantillon de la chaîne est comme ci-dessous: P>

my $text = '/F12345 FF FF this is SCF SF really MV (important stuff SH';


2 commentaires

Pas besoin d'échapper au / étant donné que ceci est dans un qr {} .


Êtes-vous sûr que c'est la partie lente de votre programme?


5 Réponses :


6
votes

Cela dépend beaucoup du profil des données que vous numérisez.

Vous identifiez la pièce de votre expression régulière qui filtre le plus d'entrée et effectuez une expression régulière plus simple plus simple pour cette expression. < P> Par exemple, si seulement 5% de votre date d'entrée contenait la chaîne 'MV' ', vous pouvez filtrer pour cette première et appliquer uniquement l'expression régulière complète plus complexe si le plus simple est vrai. < / p>

Vous auriez donc: xxx


1 commentaires

Si vous recherchez simplement une chaîne statique dans votre première passe à la recherche de mauvaises herbes, envisagez de comparer l'analyse comparative si index ('MV ») est plus rapide que de faire une correspondance de regex pour cela.



7
votes

sans voir des données d'échantillon, il est difficile de dire.

Généralement, c'est une bonne idée d'éviter d'utiliser . * . Recherchez toutes les sources possibles de ramassage inutile et éliminez-les.

Vous pourriez être capable de vous éloigner avec un Split avec une tranche si vos besoins sont simples. xxx


0 commentaires

21
votes

Il n'y a pas de réponse unique à optimiser une regex. Vous pouvez regarder ce que fait une regex particulière avec le Re Pragma: XXX

Une fois que vous voyez ce qu'il traverse la chaîne, vous voyez où cela pose des problèmes et ajuster votre regex de là. Vous en apprendrez un peu sur le moteur de regex comme vous le faites.

Vous devez également consulter Maîtriser des expressions régulières , qui vous indique comment les expressions régulières fonctionnent et pourquoi certains modèles sont plus lents que d'autres.


0 commentaires

1
votes

Backtracking est l'un des moyens les plus sûrs de tuer les performances de regex, mais, malheureusement, cela ne semble pas être un cas où vous êtes capable d'éliminer complètement le . wildcard en faveur des classes de caractères , à moins que le texte que vous capturez est interdit de contenir des caractères majuscules. (Si cette interdiction existe, vous pouvez remplacer votre . *? avec, dites, [A-Z] * .)

Vous pouvez toujours réduire la possibilité de revenir en arrière à l'aide de {} pour définir un nombre minimum / maximum de caractères à correspondre, tels que . {0,10}? Si la correspondance ne peut pas dépasser 10 caractères.


0 commentaires

3
votes

(. *) code> signifie que vous traitez avec n'importe quel nombre de répétitions de "SCF SF" avant de trouver celui qui indique que c'est la capture suivante. En le rendant non gourmand, vous manipulez toujours la capacité que même «SCF SF» apparaîtrait dans la capture après «FF». Je pense que vous manipulez beaucoup de cas que vous n'avez pas besoin.

Le meilleur moyen d'optimiser une expression régulière le rend parfois plus cryptique - mais vous trouverez définitivement des moyens de faire l'expression échouer plus tôt EM >. (. *?) code> tout en cas d'étant "gourmand" est définitivement trop em> tolérante. p>

ci-dessous est une alternative plus verbeuse, mais plus rapide à votre seconde. capturer. p> xxx pré>

Mais vous pouvez l'optimiser encore plus si vous pensez que la chaîne \ bscf \ b code> doit automatiquement faire valider la capture et n'attendre que "\ bscf sf \ b". Ainsi, vous pouvez ré-écrire comme suit: p> xxx pré>

mais vous pouvez optimiser ces chaînes encore plus par le contrôle de la rampe. Si vous pensez qu'il n'y a aucun moyen dans le monde que SCF se produirait jamais comme un mot et ne sera pas suivi de SF sur une entrée valide. Pour ce faire, vous ajoutez un autre groupe autour de lui, avec des crochets (?> Code> et ) code>. P> xxx pré>

Cela signifie que la logique correspondante n'essaie en aucun cas de réévaluer ce qu'elle a capturé. Si les personnages après cela ne sont pas «SCF SF», toute l'expression échoue. Et il échoue bien avant que cela ne puisse jamais essayer d'accueillir "MV" et d'autres sous-expressions. P>

En fait, compte tenu de certaines expressions sur le caractère unique des délimiteurs, la performance la plus rapide de cette expression serait la suivante: P>

((?:.(?! SCF))*) SCF SF


0 commentaires