/ / Expressions régulières pour faire correspondre les valeurs séparées protégées - regex, perl

Expressions régulières pour faire correspondre les valeurs séparées protégées - regex, perl

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 № 1

Amé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;