OVH Cloud OVH Cloud

Découper une chaine

7 réponses
Avatar
Theo
Bonjour,

Je souhaite "découper" une chaine en plusieurs éléments, sachant qu'un
élément est séparé du suivant par une virgule. Toutefois il faudra ignorer
une virgule si elle est située en deux apostrophes !

Exemples:

A partir de 000,bbb,222 je souhaite obtenir un tableau avec les 3 items :
000 et bbb et 222

A partir de 'aaa',2,'bb'cc',4 je souhaite obtenir un tableau avec les 4
items aaa et 2 et bb'cc et 4

A partir de 1,'xx,yy',3,'ddd' je souhaite obtenir un tableau avec les 4
items 1 et xx,yy et 3 et ddd

A partir de ,2,,4 je souhaite obtenir un tableau avec les 4 items "vide" et
2 et "vide" et 4

D'avance, un grand merci !!!

7 réponses

Avatar
dominix
Theo wrote:
Bonjour,

Je souhaite "découper" une chaine en plusieurs éléments, sachant qu'un
élément est séparé du suivant par une virgule. Toutefois il faudra
ignorer une virgule si elle est située en deux apostrophes !

Exemples:

A partir de 000,bbb,222 je souhaite obtenir un tableau avec les 3
items : 000 et bbb et 222

A partir de 'aaa',2,'bb'cc',4 je souhaite obtenir un tableau avec les
4 items aaa et 2 et bb'cc et 4

A partir de 1,'xx,yy',3,'ddd' je souhaite obtenir un tableau avec les
4 items 1 et xx,yy et 3 et ddd

A partir de ,2,,4 je souhaite obtenir un tableau avec les 4 items
"vide" et 2 et "vide" et 4

D'avance, un grand merci !!!


Text::CSV_XS permet cela.

--
dominix

Avatar
Theo
Merci pour l'information !

Cela dit, c'est sourtout pour m'entrainer d'avantage aux expressions
rationnelles que je tente de résoudre ce problème... Sans grand succès pour
l'instant.... J'ai fait quelques tentatives avec split, en essayant de
trouver une expression rationnelle qui respecte les contraintes, mais sans
grand résultat... Donc si vous aviez une piste, ce serait avec grand plaisir
!!!


"dominix" @despammed.com> a écrit dans le message de
news:4006773f$0$17126$
Theo wrote:
Bonjour,

Je souhaite "découper" une chaine en plusieurs éléments, sachant qu'un
élément est séparé du suivant par une virgule. Toutefois il faudra
ignorer une virgule si elle est située en deux apostrophes !

Exemples:

A partir de 000,bbb,222 je souhaite obtenir un tableau avec les 3
items : 000 et bbb et 222

A partir de 'aaa',2,'bb'cc',4 je souhaite obtenir un tableau avec les
4 items aaa et 2 et bb'cc et 4

A partir de 1,'xx,yy',3,'ddd' je souhaite obtenir un tableau avec les
4 items 1 et xx,yy et 3 et ddd

A partir de ,2,,4 je souhaite obtenir un tableau avec les 4 items
"vide" et 2 et "vide" et 4

D'avance, un grand merci !!!


Text::CSV_XS permet cela.

--
dominix





Avatar
dominix
[REFORMATE]

Text::CSV_XS permet cela.



Cela dit, c'est sourtout pour m'entrainer d'avantage aux expressions
rationnelles que je tente de résoudre ce problème... Sans grand
succès pour l'instant.... J'ai fait quelques tentatives avec split,
en essayant de trouver une expression rationnelle qui respecte les
contraintes, mais sans grand résultat... Donc si vous aviez une
piste, ce serait avec grand plaisir !!!



[merci de ne plus poster a l'envers et de ne pas citer les signatures]

je vous invite a la modération dans l'usage des expression rationnelles.
celle ci sont très pratique mais aussi très gourmande et ne réponde pas
à toute sorte de problèmes.
l'exemple suivant est donné dans perldoc perlre pour matcher des
regroupement (ici entre parentheses) ça devrais aider.

$re = qr{
(
(?:
(?> [^()]+ ) # Non-parens without backtracking
|
(??{ $re }) # Group with matching parens
)*
)
}x;

--
dominix


Avatar
Jedaï
J'obtiens un bon résultat sur 3 des 4 exemples que tu as proposé avec ce
split :

#!perl

use strict;
use warnings;

my $textcvs = ",2,,4";

my @fields = split /',(?!')|(?<!'),'|,(?!')/, $textcvs;
s/^'|'$//g for @fields;

$, = " ";
print @fields;
__END__

L'exemple qui pose problème est bien sûr 1,'xx,yy',3,'ddd' où mon split
le découpe en 1 xx yy 3 ddd... Je pense qu'on ne peut pas obtenir
beaucoup mieux avec un simple split, donc direction les regexs si tu en
as envie, mais c'est un problème qui doit mieux se résoudre avec une
machine à états simple (enfin pas trop...), je pense.
--
Jedaï
Avatar
dominix
Jedaï wrote:
J'obtiens un bon résultat sur 3 des 4 exemples que tu as proposé avec
ce split :

#!perl



je pense que c'est au post original de theo que tu voulais repondre ?

Avatar
Jedaï
dominix wrote:
Jedaï wrote:

J'obtiens un bon résultat sur 3 des 4 exemples que tu as proposé avec
ce split :

#!perl




je pense que c'est au post original de theo que tu voulais repondre ?




Ca me semblait assez évident, mais je continue aussi la discussion en
surenchérissant sur le fait que les regexs ne sont pas la solution
miracle, et que ici elle ne sont pas très adapté (ce que tu avais déjà
dit). :)
--
Jedai


Avatar
jl_morel
Dans l'article <4006c577$0$7159$, a
dit...

Merci pour l'information !

Cela dit, c'est sourtout pour m'entrainer d'avantage aux expressions
rationnelles que je tente de résoudre ce problème... Sans grand succès pour
l'instant.... J'ai fait quelques tentatives avec split, en essayant de
trouver une expression rationnelle qui respecte les contraintes, mais sans
grand résultat... Donc si vous aviez une piste, ce serait avec grand plaisir
!!!



Je propose :

#!/usr/bin/perl -w
use strict;

my @s = ( "000,bbb,222",
"'aaa',2,'bb'cc',4",
"1,'xx,yy',3,'ddd'",
",2,,4"
);

foreach (@s) {
print "====== $_n";
print "$+n" while ( /'(.*?)'(?:,|$)|(),|((?:^|[^'])[^,]*?)(?:$|,)/g );
}

__END__


--
J-L.M.