2009-08-20 5 views
4

Je suis assez nouveau pour les expressions régulières et j'ai besoin d'aide. J'ai besoin de filtrer certaines lignes en utilisant regex dans Perl. Je vais passer l'expression rationnelle à une autre fonction donc il faut le faire en une seule ligne.Comment puis-je combiner une condition positive et négative dans une regex?

Je veux sélectionner uniquement les lignes qui contiennent "too long" et qui ne commencent pas par "SKIPPING"

Voici mes chaînes de test:

SAUTER ce lien depuis la maturité trop longtemps
TKIPPING ce lien depuis échéance trop longue
SLAPPING ce lien depuis la maturité trop longtemps
Bonjour cette maturité trop longue
c'est trop long
bonjour il

La règle regex doit correspondre à ce qui suit sur « trop long»:

SAUT ce lien depuis la maturité trop longtemps
SLAPPING ce lien depuis la maturité trop longtemps
Bonjour cette maturité trop longtemps
c'est trop long

et il devrait sauter:

"Bonjour", car il ne contient pas 'trop long'
"SAUT ce lien depuis trop longtemps la maturité" parce qu'elle containst 'SAUT'

Répondre

11
/^(?!SKIPPING).*too long/ 
+0

Très cool. Merci. J'ai un moyen d'apprendre l'expression rationnelle! – autodidact

+0

Voilà comment le look-behind négatif est fait en Perl. Pas de signe <<. –

+4

En fait, c'est un lookahead négatif. Le lookbehind négatif a en effet un '<' ... la syntaxe est '(? chaos

-2

utilisant lookbehind négatif:

(?<!^SKIPPING)too long$ 
+0

Ne fonctionne pas. Essayez-le. – chaos

+0

Je ne suis pas sûr de la syntaxe?

+0

Vous ne pouvez pas utiliser un lookbehind de longueur variable. – Axeman

10

Personnellement, je ferais cela comme deux regex distinctes juste pour le rendre plus clair.

while (<FILE>) 
{ 
    next if /^SKIPPING/; 
    next if !/too long/; 

    ... do stuff 
} 
+0

-1 dans Pas de réponse. –

+9

Que voulez-vous dire "pas une réponse"? Il accomplit exactement ce qu'il veut, mais pas exactement comme il le pensait. Pour moi, c'est une réponse. –

1

Utilisez une vue d'ensemble; voir this explanation of regex lookaround.

^(?!SKIPPING).*too long 
+0

Ce site est tout à fait faux sur la syntaxe pour look-behind négatif, malheureusement. –

+0

@Daniel: non, ce n'est pas le cas. Je pense que vous êtes confus ici. – ysth

+0

@Daniel: En quoi le site est-il faux? Lookbehind négatif prend la forme '(?

3

Je suppose que vous peut-être après une seule regex mais je préfère diviser en quelque chose de plus facile à lire comme ceci:

use strict; 
use warnings; 

for my $line (<DATA>) { 
    next if $line =~ m/^SKIPPING/; 
    next if $line !~ m/too long/; 

    # do something with $line 
    chomp $line; 
    say "Found: ", $line, ':length=', length($line); 
} 

__DATA__ 
SKIPPING this bond since maturity too long 
TKIPPING this bond since maturity too long 
SLAPPING this bond since maturity too long 
Hello this maturity too long 
this is too long 
hello there 
-1
/^(?<!SKIPPING).*too long$/ 

Matchs lignes que vous recherchez. Le signe dollar à la fin l'amène à correspondre uniquement aux chaînes qui se terminent par «trop long».

Espérons que cela aide!

Questions connexes