2009-07-08 5 views
1

Hier ist ein interessantes Problem. Ist es möglich, eine Zeichenfolge nur auf der letzten passenden Regex zu teilen?Perl: Gibt es eine Möglichkeit, nur die letzte Regex-Übereinstimmung zu teilen?

Betrachten Sie die folgende Liste der Spaltenüberschriften von meiner Datendatei (die sich entlang der gleichen Linie zu lesen, wobei laschen getrennt):

Frequency Min 
Frequency Avg 
Frequency Max 
Voltage L1 Min 
Voltage L1 Avg 
Voltage L1 Max 
Active Power L1 Min 
Active Power L1 Avg 
Active Power L1 Max 

Derzeit meine Daten als Array zu jeder Spalte angehängt wird (zB @{ $data{Frequency Min} }, @{ $data{Active Power L1 Avg} }). Es wäre nett, Sub-Hashes basierend auf den Min-, Max- und Avg-Schlüsselwörtern erstellen zu können (z. B. @{ $data{Frequency}{Min} }, @{ $data{Active Power L1}{Avg}), weshalb ich den letzten Leerraum jeder Überschrift teilen möchte.

Beachten Sie, dass die Situation durch die Tatsache erschwert wird, dass eine beliebige Anzahl von Leerzeichen auftreten kann, bevor das finale Match gefunden wird.

Ich habe daran gedacht, die Saite umzudrehen, einmal den Split durchzuführen und dann beide Saiten separat umzukehren, aber das ist zu chaotisch für meinen Geschmack. Gibt es einen besseren Weg, dies zu tun?

Antwort

10

Sie können eine reine Regex verwenden, anstatt split mit:

my ($label, $type) = /(.*)\s+(\S+)/; 
+0

Können Sie uns erklären, was das tut innerhalb der Regex (. *)? – Zaid

+2

Die. * Entspricht allem ("beliebige Anzahl von beliebigen Zeichen"). Es ist gierig und wird so viel wie möglich zusammenpassen. Das \ S + stimmt mit allen Nicht-Leerzeichen-Zeichen überein ("mindestens ein Nicht-Leerzeichen"); Da es auch gierig ist, bedeutet dies, dass in der Praxis das \ S + nur dem letzten Token entspricht, da das. * alle vorhergehenden Tokens übernommen hat. –

+0

. * Entspricht einer beliebigen Zeichen- folge, und die umgebenden Parens machen diesen Teil des Ausdrucks zum ersten Mitglied der Liste, die vom Übereinstimmungsausdruck zurückgegeben wird. – mkb

2

Split nur auf Räume, die nach ihnen keinen anderen Platz haben?

($subname, $subtype) = split/(?!.*?)/, $heading, 2; 
+0

Was bedeutet diese Sekunde? genau erreichen? – Zaid

+2

Kein Effekt im Ergebnis, nur lässt die Regex-Engine wissen, dass sie aufhören kann, den ersten gefundenen Raum zu betrachten. Ohne es passt das. * So viel wie möglich, was bis zum letzten Leerzeichen wäre. – ysth

0

Angenommen, Sie alle Arten wissen:

($label, $type) = /(.*)\s*(min|avg|max)$/i; 
Verwandte Themen