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.
Je pense que vous devez clarifier. En l'état, je n'ai aucune idée de ce que vous voulez accomplir. –
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 –