2010-12-19 19 views
2

Ich versuche, den besten Weg zu finden, eine Linie, die wie folgt aussieht zu analysieren:Extract n-te Vorkommen mit Perl Regex


Explicit|00|11|Hello World|12 3 134||and|blah|blah|blah

Ich möchte nur das Zeug extrahieren zwischen dem 6. und 7. vertikalen Balken |
Ich habe versucht, so etwas wie

if ($line =~ /^(.*\|){6}(\w*)\|/) { 
    print $2; 
} 

Das Problem ist, dass der erste Teil der längste Sequenz passend möglich, weil die .* zu sein scheint, vielleicht ist es etwas anderes ich verwenden soll. Zwischen den vertikalen Balken befinden sich alphanumerische Zeichen, Leerzeichen und Satzzeichen.

Sollte ich die kürzeste zwischen ihnen übereinstimmen?

+0

Warum nicht einfach auf "|" aufteilen? – Shurdoof

+0

Sie haben Recht. Ich denke, ich habe gerade eine Weile mit Regex gespielt, also dachte ich nicht einmal an andere Funktionen :) – MCH

Antwort

8

Sie können stattdessen .*? verwenden, um die * zu modifizieren, um weniger zu bevorzugen.

Dies könnte immer noch an der falschen Stelle übereinstimmen, wenn das gewünschte Feld Nicht-Wort-Zeichen hat; Um dies zu verhindern, können Sie entweder explizit etwas sagen, aber | (([^|]*\|){6}) oder deaktivieren Sie die Rückverfolgung für diesen Teil (((?>.*?\|)){6}).

Oder Sie könnten nur Split verwenden:

if (my $seventh = (split /\|/, $line, 8)[6]) { 
    print $seventh; 
} 

(die 8 ist optional und teilt aufgeteilt nicht versuchen, mehr zu stören, nach dem 7. Erreichen |)

+0

Oh, das ist großartig. Ja, ich werde nur Split verwenden, macht mehr Sinn. – MCH

3

Verwendung gespalten. So etwas wie my @fields = split /\|/, $str sollte funktionieren. Dann indizieren Sie einfach das Feld, an dem Sie interessiert sind (auch leere Felder bleiben erhalten). | muss als Escape-Operator maskiert werden.