Je voudrais avoir une expression régulière pour faire correspondre des valeurs séparées avec des valeurs protégées pouvant contenir le caractère séparateur.
Par exemple:
"A,B,{C,D,E},F"
donnerait:
- "UNE"
- "B"
- "{C, D, E}"
- "F"
Veuillez noter que les valeurs protégées peuvent être imbriquées, comme suit:
"A,B,{C,D,{E,F}},G"
donnerait:
- "UNE"
- "B"
- "{C, D, {E, F}}"
- "G"
J'ai déjà codé cette fonctionnalité avec une itération de caractère comme suit:
sub Parse
{
my @item;
my $curly;
my $string;
foreach(split //)
{
$_ eq "{" and ++$curly;
$_ eq "}" and --$curly;
if(!$curly && /[,:]/)
{
push @item, $string;
undef $string;
next;
}
$string .= $_;
}
push @item, $string;
return @item;
}
Mais ce serait définitivement beaucoup plus agréable avec une expression rationnelle.
Réponses:
1 pour la réponse № 1Amélioré de la réponse de nhahtdh.
$_ = "A,B,{C,D,E},F";
while ( m/({.*?}|((?<=^)|(?<=,)).(?=,|$))/g ) {
print "[$&]n";
}
Amélioré à nouveau. Veuillez regarder celui-ci!
$_ = "A,B,{C,D,{E,F}},G";
while ( m/({.*}|((?<=^)|(?<=,)).(?=,|$))/g ) {
print "$&n";
}
Il obtiendra:
A
B
{C,D,{E,F}}
G
2 pour la réponse № 2
Une expression régulière qui prend en charge l'imbrication se présenterait comme suit:
my @items;
push @items, $1 while
/
(?: ^ | G , )
(
(?: [^,{}]+
| (
{
(?: [^{}]
| (?2)
)*
}
)
| # Empty
)
)
/xg;
32
$ perl -E"$_ = shift; ... say for @items;" "A,B,{C,D,{E,F}},G"
A
B
{C,D,{E,F}}
G
Suppose une entrée valide car il ne peut pas extraire et valider en même temps. (Eh bien, non sans rendre les choses vraiment compliquées.)
1 pour la réponse № 3
$a = "A,B,{C,D,E},F";
while ($a =~ s/({[{}w,]+}|w)//) {
push (@res, $1);
}
print "@res: @resn"
Résultat:
@res: A B {C,D,E} F
Explication: nous essayons de faire correspondre le bloc protégé {[{}w,]+}
ou juste un seul personnage w
successivement dans une boucle, en la supprimant de la chaîne d'origine s'il y a correspondance. Chaque fois qu'il y a une correspondance, nous la stockons (ce qui signifie $1
) dans le tableau, et voilà!
0 pour la réponse № 4
Voici une expression régulière en bash:
chronos@localhost / $ echo "A,B,{C,D,E},F" | grep -oE "({[^}]*}|[A-Z])"
A
B
{C,D,E}
F
0 pour la réponse № 5
Essayez cette expression régulière. Utilisez l'expression régulière pour faire correspondre et extraire le jeton.
/({.*?}|(?<=,|^).*?(?=,|$))/
Je n'ai pas testé ce code en Perl.
Il y a une hypothèse sur la façon dont le moteur regex fonctionne ici (je suppose qu'il essaiera de correspondre à la première partie {.*?}
avant la deuxième partie). Je suppose également qu'il n'y a pas de parenthèse bouclée imbriquée et de parenthèses bouclées mal appariées.
-2 pour la réponse № 6
$s = "A,B,{C,D,E},F";
@t = split /,(?=.*{)|,(?!.*})/, $s;