2009-09-17 9 views
-2

J'ai une commande DOS qui sort comme suit (juste un exemple contenant 3 résultats):Comment obtenir des valeurs par les opérations de chaînes Perl?

 
The Scheme GUID: 123-abc (Scheme1) * 

The Scheme GUID: 456-def (Scheme2) 

The Scheme GUID: 789-ghi (Scheme3) 

J'Invoquer le programme de ligne de commande à partir d'un script Perl et je veux stocker deux résultats dans une structure:

 
**123-abc** (alphanumeric value) & 
**Scheme1**(name of the scheme) 
*(values obtained from the results mentioned above in the eg)* 
  1. Je veux savoir comment stocker les 3 résultats ci-dessus (la valeur alphanumérique et le nom Scheme) et mis dans un tableau de 3 structures.

  2. J'ai besoin d'obtenir le schéma qui est étoilé (comme montré ci-dessus Scheme1 est étoilé) et l'assigner à une variable globale.

+2

Je pense que vous devez clarifier. En l'état, je n'ai aucune idée de ce que vous voulez accomplir. –

+0

je veux récupérer ces chaînes (alphanumericvalue et nom de schéma) du résultat obtenu de la commande DOS .... Je dois choisir les deux (par exemple: <123-abc> & ) du résultat ceux qui utilisent uniquement les opérations de chaîne PERL. et aussi j'ai besoin de choisir le nom du régime du résultat (qui est joué dans le résultat) en utilisant les opérations de chaîne PERL et –

Répondre

4

Cela ressemble à un travail pour un regex et un array of hashes. Tout d'abord, créons un modèle qui peut trouver l'information. Vous recherchez une chaîne constante "The Scheme GUID: " suivie d'une chaîne contiguë de caractères alphanumériques et de traits d'union suivie d'un espace, puis d'une chaîne contiguë de caractères alphanumériques entourés de parenthèses. En regex, c'est /The Scheme GUID: [a-zA-Z0-9-]+ \([a-zA-Z0-9]+\)/. Maintenant, cela ne fera que correspondre à la chaîne, et nous voulons tirer des morceaux de celui-ci, nous avons donc besoin d'ajouter des captures à la regex et attraper son retour:

my ($guid, $scheme) = /The Scheme GUID: ([a-zA-Z0-9-]+) \(([a-zA-Z0-9]+)\)/; 

Les () sont utilisés pour désigner les parties que nous voulons pour sauver de la chaîne et sont appelés des captures.

Maintenant que nous avons les valeurs, vous voulez créer une structure de type enregistrement. En Perl, vous utilisez couramment un hachage à cet effet:

my %record = (
    guid => $guid, 
    scheme => $scheme 
); 

Vous pouvez maintenant accéder au guid en disant $record{guid}. Pour construire un tableau de ces documents, il suffit de pousser le disque sur un tableau:

my @records; 
while (<>) { 
    my ($guid, $scheme) = /The Scheme GUID: ([a-zA-Z0-9-]+) \(([a-zA-Z0-9])\)/; 
    my %record = (
     guid => $guid, 
     scheme => $scheme 
    ); 
    push @records, \%record; 
} 

Vous pouvez maintenant accéder au système du troisième disque comme celui-ci: $records[2]{scheme}.

Votre dernière exigence nécessite une modification de l'expression régulière. Vous devez rechercher cette étoile et faire quelque chose de spécial si vous le voyez. Malheureusement étoile signifie quelque chose à regexes, de sorte que vous devrez y échapper comme vous l'avez fait avec des parenthèses.Et l'étoile est pas toujours présent, vous aurez donc besoin d'utiliser non-regroupement des parenthèses (?:) et ? quantificateurs dire l'expression rationnelle qui ne correspond pas à cette partie de la chaîne est correct:

my ($guid, $scheme, $star) = /The Scheme GUID: ([a-zA-Z0-9-]+) \(([a-zA-Z0-9]+)\)(?: (\*))?/; 

Le regex est devenu très long et difficile à lire, à ce stade, il est donc probablement une bonne idée d'utiliser le drapeau /x et ajouter quelques espaces et des commentaires à la regex:

my ($guid, $scheme, $star) = m{ 
    The [ ] Scheme [ ] GUID: 
    ([a-zA-Z0-9-]+)   #capture the guid 
    [ ] 
    \( ([a-zA-Z0-9]+) \) #capture the scheme 
    (?: 
     [ ] 
     (\*)    #capture the star if it exists 
    )? 
}x; 

Ils je voudrais ainsi écrire un programme comme celui-ci est:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $primary_record; 
my @records; 
while (<DATA>) { 
    next unless my ($guid, $scheme, $star) = m{ 
     The [ ] Scheme [ ] GUID: [ ] 
     ([a-zA-Z0-9-]+)   #capture the guid 
     [ ] 
     \( ([a-zA-Z0-9]+) \) #capture the scheme 
     (?: 
      [ ] 
      ([*])    #capture the star if it exists 
     )? 
    }x; 
    my %record = (
     guid => $guid, 
     scheme => $scheme, 
     starred => defined $star ? 1 : 0 
    ); 

    if ($record{starred}) { 
     $primary_record = \%record; 
    } 

    push @records, \%record; 
} 

print "records:\n"; 
for my $record (@records) { 
    print "\tguid: $record->{guid} scheme: $record->{scheme}\n"; 
} 
print "primary record is $primary_record->{guid}\n"; 

__DATA__ 
The Scheme GUID: 123-abc (Scheme1) * 
The Scheme GUID: 456-def (Scheme2) 
The Scheme GUID: 789-ghi (Scheme3) 

Si vous avez les données dans un tableau, pour vous pouvez remplacer la boucle while avec une boucle for:

for my $line (@lines) { 
    next unless my ($guid, $scheme, $star) = $line =~ m{ 
     The [ ] Scheme [ ] GUID: [ ] 
     ([a-zA-Z0-9-]+)   #capture the guid 
     [ ] 
     \( ([a-zA-Z0-9]+) \) #capture the scheme 
     (?: 
      [ ] 
      ([*])    #capture the star if it exists 
     )? 
    }x; 

L'idiome next unless match dit que pour obtenir une autre ligne si celui-ci ne correspond pas à la regex. Le m{regex} est la forme généralisée de /regex/. J'ai tendance à utiliser la forme généralisée lorsque j'étire une regex sur plusieurs lignes, car cela facilite la correspondance entre le début et la fin de l'expression rationnelle dans mon éditeur.

+1

Je pense que stack_pointer est EXTINCT vous doit quelques heures de salaire. – Ether

+0

@Ether: quelques minutes de l'heure de Chas. Je suis sûr. Si vous utilisiez stack_pointer est l'heure de EXTINCT, vous êtes probablement là aussi. – ysth

+0

Merci Owens pour votre réponse. Mais une chose que je ne suis pas clair si je stocke le résultat-> Le schéma GUID: 123-abc (Scheme1) * Le schéma GUID: 456-def (Scheme2) Le schéma GUID: 789-ghi (Scheme3 dans un tableau de longueur 3 ... comment puis-je faire le code ?? et aussi dint comprendre ... "à moins que ma" déclaration qui a m {<** sumthing **} x; Qu'est-ce que m et x représentent? Pourriez-vous aider ?? –

Questions connexes