Découper une chaine de caratcere complexe

a marqué ce sujet comme résolu.

Bonjour, j’ai un probleme assez compliqué a traité en C, je recois cette chaine de caractere :

1
 "command1";"sleep 30; command2 -a ; command3";"command4="MyTest""

je voudrais la séparer et avoir en sortie :

1
2
3
command1
sleep 30; command2 -a ; command3
command4="MyTest"

j’ai essayé de faire avec la fonction strtok mais j’ai pas le résultat voule, je ne pense pas que strtok soit une bonne idée dans ce contexte, voila ce que j’ai :

1
2
3
4
5
6
7
   char mystring[1024]="\"command1\";\"sleep 30; command2 -a ; command3\";\"command4=\"MyTest\"\"";
   token = strtok(mystring, "\";\"");

   while( token != NULL ) {
      error(token);
      token = strtok(NULL, s);
   }

et le résultat :

1
2
3
4
5
command1
"sleep 30
command2 -a
command3"
"command4="MyTest""

du coup es ce que je m’y prend mal avec strtok, ou bien c’est impossible/tres compliqué avec cette fonction ? dans ce cas auriez vous une autre solution, comme par exemple une fonction "regex", pour analyser des expressions réguliere comme on peut l’avoir en C++, python…

dans mon cas, il faut considerer mla chaine de caractere comme un tableau et chaque élèvement est mis entre double quote et est séparer par des ";"

"element1";"element2"…etc.

sauf que y’a les cas batard que je dois prendre en compte : "element01;element02";"elemeent1" "element1="monelement1"";"element2"

Comme je le vois, il suffit de supprimer le 1er et le dernnier caractere qui sont des double quote, puis de séparer mes élements des uqe je rencontre un double quote, point virgule, double quote donc ceci : ";"

+0 -0

Pour des cas comme ça, on est sensé faire un parser.

Si tu souhaites utilisé des regex. Il n’y a rien de standard mais ça existe. Par exemple GNU Regex1 Gnulib regex .

Tu peux toujours “tricher”. Plus ou moins facilement en fonction de si tu peux ou pas échaper des " en faisant \" dans une chaine.


  1. Apparement, GNU Regex n’est plus maintenu, c’est domage. Gnulib Regex est son remplacent, c’est pas plus mal, c’est plus facile à utiliser. 

+0 -0

Salut,

C’est possible avec strtok (enfin il me semble, je n’ai pas testé pour vérifier), mais tu ne pas pouvoir utiliser les jetons directement tels que retournés, il va falloir prendre en compte le contexte pour connaître les imbrications.

Ce sont ces mêmes contextes qui vont t’empêcher d’utiliser des expressions rationnelles pour cela (le langage que tu cherches à analyser n’est pas rationnel). Après il y a des moteurs de regex qui sont étendus de façon à supporter des langages algébriques, mais ça ne me paraît pas être une bonne idée.

Edit : Bon en fait ça me semble difficile avec strtok, car si tu commences par découper sur les guillemets tu localiseras difficilement les points virgules, et je ne vois pas comment pourraient être gérés les guillemets consécutifs.

La solution la plus simple serait d’itérer sur ta chaîne manuellement et de repérer les caractères. Mais le format d’entrée n’est pas terrible, parce que tu vas buter sur les cas comme "cmd=";foo";" qui paraissent légaux si j’en crois ton énoncé.

C’est surtout pas bien défini ce problème… Après tout "command1";"sleep 30; command2 -a ; command3";"command4="MyTest"" pourrait être considérée comme une longue chaîne entre guillemets (command1";"sleep 30; command2 -a ; command3";"command4="MyTest"), et donc ça paraîtrait assez naturel de renvoyer un seul token (celui dans la parenthèse précédente). Donc j’ai envie de dire qu’en l’état, ton problème n’est pas résoluble (il faudrait plus d’information sur les entrées que tu dois pouvoir traiter).

Par exemple, ça serait mieux défini si on détermine clairement quels sont les guillemets fermants et ouvrants (typiquement avec des parenthèses à la place des guillemets :p).

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte