2009-08-20 6 views
4

Ich bin ziemlich neu zu regulären Ausdrücken und brauche etwas Hilfe. Ich muss einige Zeilen mit Regex in Perl filtern. Ich werde die Regex an eine andere Funktion übergeben, so dass sie in einer einzigen Zeile ausgeführt werden muss.Wie kann ich eine positive und negative Bedingung in einer Regex kombinieren?

Ich möchte nur Linien auswählen, die "too long" enthalten und beginnen Sie nicht mit "SKIPPING"

Hier meine Test-Strings sind:

SKIPPING diese Bindung seit Fälligkeit zu lange
TKIPPING diese Bindung seit Laufzeit zu lang
SLAPPING diese Anleihe seit Laufzeit zu lang
Hallo diese Laufzeit zu lang
das ist zu lang hallo dort

Die Regex Regel sollte die folgenden auf ‚zu lange Match":

SKIPPING diese Bindung seit Fälligkeit zu lange
Slapping diese Bindung seit Fälligkeit zu lange
Hallo diese Reife zu lange
dies zu lang ist

und sollte es überspringen:

"Hallo", weil es enthält nicht 'zu lange'
"SKIPPING diese Bindung seit Fälligkeit zu lang", weil es containst 'SKIPPING'

Antwort

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

Sehr cool. Vielen Dank. Ich habe einen Weg zum Lernen Regex! – autodidact

+0

Dies ist der negative Rückblick in Perl. Kein '<' Zeichen. –

+4

Eigentlich ist das ein negativer Lookahead. Negatives Lookbehind hat tatsächlich ein '<' ... die Syntax ist '(? chaos

-2

Mit negativen Lookbehind:

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

Funktioniert nicht. Versuch es. – chaos

+0

Ich bin mir nicht sicher über die?

+0

Sie können kein Look-Behind variabler Länge verwenden. – Axeman

10

Persönlich würde ich dies als zwei separate Regex nur um es klarer zu machen.

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

    ... do stuff 
} 
+0

-1 in Keine Antwort. –

+9

Was meinst du mit "keine Antwort"? Es erfüllt genau das, was er will, nur nicht genau so, wie er es dachte. Für mich ist das eine Antwort. –

1

Verwenden Sie ein Lookahead; siehe this explanation of regex lookaround.

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

Diese Seite ist leider falsch über die Syntax für negative Look-Behind. –

+0

@Daniel: Nein, ist es nicht. Ich denke du bist hier verwirrt. – ysth

+0

@Daniel: Wie ist die Website falsch? Negatives Lookbehind nimmt die Form '(?

3

ich Sie vermuten, vielleicht nach einer einzigen Regex aber ziehe ich in etwas mehr lesbar wie folgt aufgeteilt:

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$/ 

die Linien Spiele, die Sie suchen. Das Dollarzeichen am Ende bewirkt, dass nur Zeichenfolgen gefunden werden, die mit "zu lang" enden.

Hoffe, das hilft!