Je veux diviser une chaîne avec plusieurs modèles:
ex.
my $string= "10:10:10, 12/1/2011";
my @string = split(/firstpattern/secondpattern/thirdpattern/, $string);
foreach(@string) {
print "$_\n";
}
Je veux avoir une sortie de:
10
10
10
12
1
2011
Quelle est la bonne façon de procéder?
Utilisez un classe de caractères dans le délimiteur d'expression régulière pour faire correspondre un ensemble de délimiteurs possibles.
my $string= "10:10:10, 12/1/2011";
my @string = split /[:,\s\/]+/, $string;
foreach(@string) {
print "$_\n";
}
Explication
La paire de barres obliques /.../
indique l'expression régulière ou le modèle à mettre en correspondance.
La paire de crochets [...]
désigne la classe de caractères de l'expression régulière.
À l'intérieur se trouve l'ensemble des caractères possibles qui peuvent être mis en correspondance: deux points :
, virgules ,
, tout type de caractère d'espace \s
et barres obliques \/
(avec la barre oblique inverse comme caractère d'échappement).
Le +
est nécessaire pour faire correspondre un ou plusieurs caractères précédant immédiatement celui-ci, qui est la classe de caractères entière dans ce cas. Sans cela, l'espace virgule serait considéré comme 2 délimiteurs séparés, vous donnant une chaîne vide supplémentaire dans le résultat.
Mauvais outil!
my $string = "10:10:10, 12/1/2011";
my @fields = $string =~ /([0-9]+)/g;
Vous pouvez diviser sur des non-chiffres;
#!/usr/bin/Perl
use strict;
use warnings;
use 5.014;
my $string= "10:10:10, 12/1/2011";
say for split /\D+/, $string;
Si les nombres sont ce que vous voulez, extrayez les nombres:
my @numbers = $string =~ /\d+/g;
say for @numbers;
La capture des parenthèses n'est pas requise, comme spécifié dans perlop :
Le modificateur/g spécifie la correspondance de modèle globale, c'est-à-dire la correspondance autant de fois que possible dans la chaîne. Son comportement dépend du contexte. Dans un contexte de liste, il renvoie une liste des sous-chaînes auxquelles correspondent toutes les parenthèses de capture dans l'expression régulière. S'il n'y a pas de parenthèses, il renvoie une liste de toutes les chaînes correspondantes, comme s'il y avait des parenthèses autour du motif entier.
my $string= "10:10:10, 12/1/2011";
my @string = split(m[(?:firstpattern|secondpattern|thirdpattern)+], $string);
my @string = split(m[(?:/| |,|:)+], $string);
print join "\n", @string;
Pour répondre à votre question initiale: vous cherchiez le |
opérateur :
my $string = "10:10:10, 12/1/2011";
my @string = split(/:|,\s*|\//, $string);
foreach(@string) {
print "$_\n";
}
Mais, comme le soulignent les autres réponses, vous pouvez souvent l'améliorer avec des simplifications ou des généralisations supplémentaires.
Comme vous analysez quelque chose qui est plutôt une date/heure, je me demande s'il serait plus judicieux d'utiliser DateTime :: Format :: Strptime pour l'analyser en un objet DateTime.