2009-07-08 12 views
1

Voici un problème intéressant. Est-il possible de diviser une chaîne sur la dernière regex correspondante uniquement?Perl: Y a-t-il un moyen de séparer le dernier regex uniquement?

examiner la liste suivante des têtes de colonnes de mon fichier de données (qui se lit sur la même ligne, étant languette séparée):

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 

À l'heure actuelle, mes données sont ajoutées sous forme de tableau pour chaque colonne (par exemple @{ $data{Frequency Min} }, @{ $data{Active Power L1 Avg} }). Il serait intéressant de pouvoir créer des sous-hachages basés sur les mots clés Min, Max et Avg (par exemple, @{ $data{Frequency}{Min} }, @{ $data{Active Power L1}{Avg}), raison pour laquelle je souhaite diviser le dernier espace de chaque en-tête.

Notez que la situation est rendue plus difficile par le fait qu'un nombre quelconque d'espaces blancs peut se produire avant que la correspondance finale ne soit trouvée.

J'ai pensé à inverser la chaîne, en effectuant la scission une fois puis en inversant les deux chaînes séparément, mais c'est trop compliqué à mon goût. Existe-t-il une façon plus simple de faire cela?

Répondre

10

Vous pouvez utiliser un match pur regex plutôt que d'utiliser split:

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

Pouvez-vous expliquer ce que fait la regexp (*.)? – Zaid

+2

Le. * Correspond à tout ("n'importe quel nombre de n'importe quel caractère"). C'est gourmand, et correspondra autant que possible. Le \ S + correspond à tous les caractères non-espace ("au moins un caractère non espace"); étant également gourmand, cela signifie qu'en pratique, le \ S + ne correspondra qu'au dernier jeton, car le. * aura pris tous les jetons précédents. –

+0

. * Correspond à n'importe quelle chaîne de caractères, et les parens qui l'entourent font de cette partie de l'expression le premier membre de la liste renvoyé par l'expression de correspondance. – mkb

2

de Split uniquement sur des espaces qui ont pas d'autre espace après eux?

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

Qu'est-ce que ce second '?' atteindre exactement? – Zaid

+2

Aucun effet dans le résultat, laisse simplement le moteur regex savoir qu'il peut arrêter de regarder le premier espace qu'il trouve. Sans cela, le. * Correspond autant que possible, ce qui serait jusqu'au dernier espace. – ysth

0

En supposant que vous connaissez tous les types:

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