2010-01-11 8 views
1

J'apprends l'exemple de code de split function.extension de fonction partagée

Exemple de code.

#!C:\Perl\bin\perl.exe 
use strict; 
use warnings; 

my $info = "Caine:Michael:Actor:14, Leafy Drive"; 
my @personal = split(/:/, $info); 
# @personal = ("Caine", "Michael", "Actor", "14, Leafy Drive"); 

Si changer le $info = "Caine Michael Actor /* info data */"; Comment utiliser le split(/ /, $info) pour exporter le résultat ci-dessous.

# @personal = ("Caine", "Michael", "Actor", "info data"); 

Merci.

+4

Quelle partie avez-vous des difficultés avec exactement? Qu'avez-vous essayé jusqu'à présent? – Ether

+0

Salut Ether, Peut-être que j'ai posté une question stupide. J'ai encore quelques difficultés avec mon projet. Parfois, je ne sais pas comment analyser ma question, peut-être que je suis déjà sur le mauvais chemin pour poster ma queston. :-) J'ai juste essayé dans le mauvais sens alors je me retournerais pour trouver un autre moyen. C'est ma méthode d'apprentissage très stupide. –

+1

Existe-t-il une bonne raison d'utiliser un espace comme délimiteur? Les exemples de code ci-dessous démontrent que l'ambiguïté crée de la complexité. Une approche courante consiste à "échapper" le délimiteur, par exemple en utilisant un backslash –

Répondre

0

Fait cuire quelque chose :). Ne fonctionne que pour vous exemple. Ne peut pas généraliser

use strict; 
use warnings; 

my $info = "Caine Michael Actor /* info data */"; 
if($info=~m{/\*\s*(.*?)\s*\*/}) 
{ 
    my $temp = $1; 
    $temp=~s{\s+}{##}g; 
    $info=~s{/\*\s*(.*?)\s*\*/}{$temp}; 
} 
my @personal = split(/ /, $info); 
foreach(@personal) 
{ 
    s{##}{ }g; 
    print "$_\n"; 
} 

Sortie:

 
C:>perl a.pl 
Caine 
Michael 
Actor 
info data

+0

@codadict, Merci beaucoup pour vos détails réponse. J'ai trouvé que c'était une solution pour mon cas. C'est magique. –

2

Il est vraiment préférable d'utiliser regex pour cela:

$info = "Caine Michael Actor /* info data */"; 
$info =~ /(\w+)\s+(\w+)\s+(\w+).*\/\*(.+)\*\//; 
@personal = ($1, $2, $3, $4); 

Principalement parce que votre chaîne d'entrée a des ambiguïtés liées à des séparateurs de mots pas faciles à manipuler par split.

Si vous vous demandez comment lire l'expression rationnelle:

/ 
    (\w+) # CAPTURE a sequence of one of more word characters into $1 
    \s+  # MATCH one or more white space 
    (\w+) # CAPTURE a sequence of one of more word characters into $2 
    \s+  # MATCH one or more white space 
    (\w+) # CAPTURE a sequence of one of more word characters into $3 
    .*  # MATCH zero or more of anything 
    \/\* # MATCH the opening of C-like comment /* 
    (.+) # CAPTURE a sequence of one or more of anything into $4 
    \*\/ # MATCH the closing of C-like comment */ 
/x 
+0

Évitez le syndrome du cure-dent penchée en utilisant un délimiteur différent et affectez la correspondance à '@ personal'. N'oubliez pas de vérifier si '@ personal' a été rempli. 'if (@personal = ~ m! ...!)'. Vous devriez également ancrer le motif. –

+1

Vous ne voulez pas vraiment faire correspondre \ w + là-bas. Peu importe ce que sont les caractères tant qu'ils ne sont pas des espaces (c'est-à-dire que vous ne vous souciez pas de savoir s'ils sont des caractères d'identification Perl), vous devriez donc faire correspondre \ S + –

+0

Mieux vaut 'if (@personal = $ info = ~ /.../) {...} '. ** Ne jamais utiliser «$ 1» et amis inconditionnellement! ** –

4

approche alternative:

Avez-vous pensé à utiliser la version 3 paramètres de Split:

$info = "Caine Michael Actor /* info data */"; 
@personal= split(' ',$info,4); 

résultant dans

@personal=('Caine','Michael','Actor','/* info data */'); 

alors vous devez supprimer / ** / .. pour obtenir votre résultat ...

+1

soupir, je ne peux pas obtenir le slash-astérisque et astérisque-slash pour montrer .. – lexu

+0

Salut Lexu, Merci pour votre réponse. Je n'ai jamais envisagé d'utiliser la version à 3 paramètres de split avant. Tu m'as appris plus sur split(). –

1

car il n'y a pas encore de réponse qui gère le cas général, va ici:

split est pas votre meilleur Pariez ici, et puisque le délimiteur peut être à la fois un caractère apparié et non-apparié, il sera plus clair d'inverser le problème et de décrire ce que vous faites quoi correspondre, qui dans ce cas est soit une chaîne de caractères non spatiaux, soit le contenu de commentaire de style ac.

use strict; 
use warnings; 

my $info = "Caine Michael Actor /* info data */"; 
my @personal = grep {defined} $info =~ m! /\* \s* (.+?) \s* \*/ | (\S+) !xg; 

say join ', ' => @personal; 

qui renvoie une liste de mots/contenu des commentaires dans une séquence que vous avez besoin. La syntaxe surligneur ne met pas en surbrillance la regex ci-dessus correctement, la regex est tout entre !

Questions connexes