2012-05-11 1 views
1

Utilisation du suivi regex:En utilisant l'évaluation paresseuse sur une grande expression régulière (et pas seulement *.?)

\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client .*?\] .*? Using HTTP not .*?<br /> 

Je reçois les résultats suivants (où cases jaunes indiquent un match):

Sublime Text 2

texte brut:http://pastebin.com/vSi0mLGv

Les deux sections du bas sont correc t. Je veux toutes les sections qui contiennent: &lt;&lt;&lt;NOTICE&gt;&gt;&gt; Non-Prod Server: Using HTTP not HTTP/S

La partie supérieure contient cependant la chaîne correcte (similaire aux deux bas), mais vient aussi avec un tout autre morceau que je ne veux pas:

[Thu May 10 17:43:48 2012] [error] [client ::1] Current Name: 
DashboardBar_projAnnualReview200, referer: http:// 
localhost/test/pages/TestPage.php<br />` 

Je sais que cela revient à regex étant gourmand, mais comment puis-je faire pour faire une évaluation paresseux pour le <br />, si c'est même la bonne façon de s'y prendre. J'ai essayé (<br />)*? et d'autres en vain.


Autres informations: J'utilise Sublime Text 2, et d'effectuer une recherche regex si quelqu'un a voulu recréer l'image.

+0

Just FYI, [évaluation paresseuse] (http://en.wikipedia.org/wiki/Lazy_evaluation) n'a rien à voir avec regexes. Le mot "paresseux" a été utilisé très tôt pour décrire la variante non gourmande des quantificateurs regex, et c'était une erreur. "Non-avide" est un mot bien meilleur pour eux, et "réticent" encore plus précis. –

Répondre

4

L'avidité n'est pas le problème, l'empressement est. Le moteur regex commence à essayer de correspondre à la première occasion, et il n'abandonne pas tant que toutes les possibilités n'ont pas été épuisées. Rendre les quantificateurs non gourmands ne change pas cela, cela change simplement l'ordre dans lequel les possibilités sont essayées.

Ce n'est pas le * dans .* qui cause votre problème, c'est le .. Vous devez utiliser quelque chose de plus restrictif, car cela permet au match de démarrer trop tôt. Ce regex fonctionne comme on le souhaite parce que je l'ai remplacé le .*? avec [^][]*, qui correspond à tous les caractères sauf ] ou [:

\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client [^][]*\] [^][]* Using HTTP not .*?<br /> 

Je ne sais pas quelle saveur regex utilise Sublime Text, vous devrez peut-être échapper à la place parenthèses à l'intérieur de la classe de caractères:

\[\w* \w* \d{2} [\w:]* \d{4}\] \[error\] \[client [^\]\[]*\] [^\]\[]* Using HTTP not .*?<br /> 
2

Vous voulez dire "réticent", pas "paresseux".

Il ne devrait pas y avoir d'intervention <br />, n'est-ce pas? Quelque chose comme ((?!<br />).)* pourrait fonctionner.

+0

Oui, ça marche aussi. Cela remplacerait le '. *?' Dans l'expression rationnelle originale, tout comme je l'ai fait avec '[^] [] *'. –

+0

Cela n'a pas vraiment fonctionné dans ma situation mais les deux réponses m'ont aidé à en apprendre un peu plus sur regex. Merci! –

Questions connexes