IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Comment découper une chaine de caractère chinois, japonais, thai ?


Sujet :

Langage Delphi

  1. #1
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut Comment découper une chaine de caractère chinois, japonais, thai ?
    Bonjour tout le monde !

    Voilà, j'aimerais savoir comment découper correctement une chaine chinoise, japonaise, thai...

    Je m'explique, dans mon programme j'effectue du découpage de chaine.

    Pour cela, j'utilise les fonctions Copy, Pos, Length...

    Pour du français, il n'y a aucun problème car 1 caractère = 1 octet.

    Pour du chinois, du japonais ou du thai, c'est plus compliqué car 1 caractère peut aller jusqu'à 4 octets.

    * Il faut que j'arrive à découper la chaine japonaise correctement, par exemple, pour que le dernier idéogramme soit correct.

    Auparavant j'utilisais Delphi 6 et les composants d'affichage ne gère pas l'unicode. De ce faite, j'ai décidé d'utiliser Delphi 2010.
    http://dgriessinger.developpez.com/d...i2009-unicode/

    Selon vous, comment dois-je faire pour couper une chaine ? en tenant compte de ma contrainte ? Cf. *

    Exemple (ici chinois):
    Chaine:= 'ㅈㅈㅈㅈ';
    Length('ㅈ') égale 2.
    Length('ㅈㅈㅈㅈ') égale 8.

    Lorsque j'effectuer Copy('ㅈㅈㅈㅈ', 1, 3) je n'obtiens pas : ㅈㅈㅈ

    Comment faire ?
    Attention, pour le thai je peux avoir des caractères sur 2 octets et d'autres, sur octets.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 455
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 455
    Points : 24 867
    Points
    24 867
    Par défaut
    Je n'ai plus ma Trial Delphi 2009 et je n'ai même pas encore installé Delphi 2010 Architect, je ne pourrais que t'aider théoriquement

    On peut penser que Copy est rester Ansi
    On peut espérer qu'il y ait un équivalent AnsiLeftStr comme UniCodeLeftStr\WideLeftStr

    Par Attention, les chaines Delphi sont en UniCode 16 Bits (UTF-16 je crois) !
    Ce n'est pas de l'UTF-8, donc cela ne varie pas de 1 à 4 mais resté à 2 tout le temps

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Copy(chaine, 1 * SizeOf(Char), 3 * SizeOf(Char))
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    en fait il s'est mal exprimé, par "taille des caractères" il faut comprendre longueur en caractères d'un logogramme ce qui ne devrait pas poser de problèmes tout étant bien définit en asie ... ou presque.

    bref, cela rend l'exercice asse acrobatique tout de même, sauf peut être pour le coréen moderne qui s'écrit avec une ponctuation occidentale.
    mais entre les kanji, kana, katakanas, hiraganas, rômaji, hanja, gairaigo, kango, etc, je suis curieux de voir la tête de la fonction au final.

    même google à du mal :
    龍剣によって、言葉で傷つけることは死んだしていません。

    ce qui devrait être :
    Le dragon qui ne périt pas par l'épée peut tout de même être blessé par les mots.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  4. #4
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Merci de vos réponses.

    On peut penser que Copy est rester Ansi
    On peut espérer qu'il y ait un équivalent AnsiLeftStr comme UniCodeLeftStr\WideLeftStr
    - C'est justement ce que je cherche : je ne sais pas s'il existe de nouvelle fonction permettant de gérer correctement les caractères sur plusieurs octets. En tout cas, je ne les ai pas trouvé. Si vous savez quoi utiliser, n'hésiter pas.
    - De plus, j'ai une version Trial de Delphi 2010 et je n'arrive pas à avoir l'aide.

    Par Attention, les chaines Delphi sont en UniCode 16 Bits (UTF-16 je crois) !
    Ce n'est pas de l'UTF-8, donc cela ne varie pas de 1 à 4 mais resté à 2 tout le temps
    - Je ne sais pas comment sont codé les chaines en Delphi..., j'ai une problématique, j'essai de la résoudre. Mais c'est toujours bon à savoir. C'est une certitude ce que tu dis ?

    Copy(chaine, 1 * SizeOf(Char), 3 * SizeOf(Char))
    - Ceci ne fonctionne pas.
    - Dans mon cas, Char = 2
    - Ma chaine = ชั่
    - Il tronque ma chaine à partir du 2e octets et copie les 6 octets suivant
    => La solution serait de commencer à 1 et de copier les X octets défini pour ce caractère ชั่.
    Attention car si j'écris la chaine japonaise : ชั่か
    ชั่ = 3 octets
    か = 1 octet

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 691
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 691
    Points : 13 121
    Points
    13 121
    Par défaut
    Citation Envoyé par pepito62
    Attention car si j'écris la chaine japonaise : ชั่か
    ชั่ = 3 octets
    か = 1 octet
    Tu mélanges un peu .

    Le premier "mot" est thaïlandais et contient 3 char (6 octets), 1 consonne et 2 voyelles. Dans cette langue, les voyelles peuvent s'écrire au dessus d'une consonne.

    Le deuxième est lui japonais, 1 char (2 octets).

    Citation Envoyé par pepito62
    Exemple (ici chinois):
    Chaine:= 'ㅈㅈㅈㅈ';
    Lorsque j'effectuer Copy('ㅈㅈㅈㅈ', 1, 3) je n'obtiens pas : ㅈㅈㅈ
    Euhh. Ca c'est du coréen...

    J'ai fait un essai de copie sous D2009 et la longueur renvoyée est correct (4 char) et la copie fonctionne !
    Sinon, tu as des fonctions pour travailler en multi-bytes dans SysUtils.pas et Character.pas. CharToByteIndex, CharLength, etc.

  6. #6
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Merci pour la clarification Andnotor.

    En effet, je mélange un peu tout

    Pour être clair :
    On va dire que j'ai une form avec un TEdit.
    - On peux saisir du français, du chinois, du thai, du japonais... (en fonction du pays où mon logiciel est utilisé)
    (Mais une seule langue à la fois, pas de mélange)
    Ceci est sauvegardé dans une Base De Donnée Oracle.

    Ensuite, j'ai une autre form qui permet d'extraire les infos de la BDD pour la sauvegarder dans un fichier.
    Dans le fichier, l'information doit être tronquer sur 5 caractères.

    Ma problématique est :
    Comment récupérer les 5 premiers caractères afin que ceci fonctionne si c'est du
    - français (1 octet)
    - chinois (certain caractère peut être codé sur 2 octets)
    - thai (certain caractère peut être codé sur 3 ou 4 octets, à vérifier)
    - japonais (certain caractère peut être codé sur 3 ou 4 octets, à vérifier)
    ...

    Quel fonction me conseilles-tu ?
    Je n'ai jamais utilisé CharToByteIndex ou CharLength, ou puis-je avoir de l'aide sur les fonctions ?

    PS : Avec la Trial de Delphi 2010, je n'ai pas les sources , je ne possède que les Dcu. Idem pour l'aide, il me marque un message d'erreur et me dit que l'aide n'est pas installé.

    Merci

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 691
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 691
    Points : 13 121
    Points
    13 121
    Par défaut
    Bon, la première chose, et là je rejoint Shai, tout tes symboles sont codés sur 16 bits. Il faut cesser de réfléchir sur 1, 2,... octets et même faire abstraction de la langue.

    Length, Copy, etc. fonctionnent correctement en unicode.
    Si tu as des erreurs de copie, je regarderais plutôt la façon dont sont extraites et gérées le données depuis Oracle.

    Travailler avec les langues asiatiques est pour le moins compliqué. Se dire je tronque au 5ème caractère peut donner à la phrase une toute autre signification... qui ne sera pas du tout la logique latine ! A quoi peuvent bien servir ces 5 caractères dans un fichier ? Un index ?

    En d'autres termes, le plus simple serait que tu nous dises la finalité du truc.

  8. #8
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Length, Copy, etc. fonctionnent correctement en unicode.
    Si tu as des erreurs de copie, je regarderais plutôt la façon dont sont extraites et gérées le données depuis Oracle.
    Le libellé dont je parle est un nom produit.
    Delphi : TEdit (MaxLength : 200)
    Oracle : Colonne varchar2(200)

    D'oracle, je récupère toute la chaine et lors de mon extraction, je dois tronquer le libellé. Car le fichier généré est envoyé à un autre logiciel.
    Mon logiciel : NomProduit (200 caracteres)
    Autre logiciel : NomProduitCourt (100 caracteres)

    Il faut le prendre comme une contrainte. Il est impossible d'agrandir le NomProduitCourt de l'autre logiciel. Et impossible de réduire NomProduit car les utilisateurs n'accepterons pas.

    Travailler avec les langues asiatiques est pour le moins compliqué. Se dire je tronque au 5ème caractère peut donner à la phrase une toute autre signification... qui ne sera pas du tout la logique latine ! A quoi peuvent bien servir ces 5 caractères dans un fichier ? Un index ?

    En d'autres termes, le plus simple serait que tu nous dises la finalité du truc.
    Voilà tout mon problème. Je suis bien d'accord que tronqué en plein milieu d'une chaine ne donnera pas la même signification.

    => C'est pour cela que je dois tronquer la chaine correctement afin d'avoir tous les "idéogrammes" en entier.
    Le problème se pose surtout avec du thai, du japonais...car le symbole est codé sur + de 16 bits.
    Exemple, comme tu l'as dit : ชั่ = 1 consonne et 2 voyelles

    Soit je prends ce dernier caractère ชั่, en entier (1 consonne et 2 voyelles), soit je m'arrête au précédent.

  9. #9
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Petite question si on change SysLocale.FarEast à true va-t-il changer le comportment de la macro SizeOf ?

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 691
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 691
    Points : 13 121
    Points
    13 121
    Par défaut
    Certainement pas puisque SizeOf n'est ni une macro, ni une fonction mais un élément syntaxique qui permet de déterminer la taille d'une variable à la compilation.

  11. #11
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Andnotor,

    En vue de mes réponses apportées.

    Comprends-tu mieux ma problématique ? As-tu encore des questions ? Que me conseilles-tu, etc. ?

    Merci

  12. #12
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Sinon je parlais d'un besoin de tronquer le nom produit lors de la génération d'un fichier mais il existe X cas comme celui-ci.

    Par exemple :
    - dans une édition, il y a tellement d'information sur la page que nous devons tronquer certaines informations, le nom produit en fait partie.

  13. #13
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 691
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 691
    Points : 13 121
    Points
    13 121
    Par défaut
    Désolé, mais là je sèche...

  14. #14
    Membre habitué

    Inscrit en
    Février 2005
    Messages
    356
    Détails du profil
    Informations forums :
    Inscription : Février 2005
    Messages : 356
    Points : 175
    Points
    175
    Par défaut
    Mais comment font les thailandais lorsqu'ils créent un programme ? Ils utilisent jamais de substr, copy, length...Ya bien un moyen !

    Sinon avant de poster ici, j'avais déjà poster dans la partie algo. Et certaine personne m'ont dit de décoder les bits du caractère.

    http://www.developpez.net/forums/d86...i/#post4930411

    J'ai essayé mais apparemment, la méthode ne fonctionne pas. Quelques choses vous éclaire ?

    Sinon pour info, ma base oracle est paramétré en utf8. AL32UTF8.

Discussions similaires

  1. Bash - Découper une chaine de caractères
    Par nicolas.pissard dans le forum Shell et commandes GNU
    Réponses: 13
    Dernier message: 16/12/2014, 13h18
  2. Réponses: 2
    Dernier message: 03/10/2005, 16h23
  3. Comment découper une chaîne de caractères en VBA
    Par TomPad dans le forum Access
    Réponses: 3
    Dernier message: 23/06/2005, 09h58
  4. Réponses: 2
    Dernier message: 14/01/2005, 15h40
  5. comment vider une chaine de caractère
    Par gaut dans le forum C
    Réponses: 13
    Dernier message: 12/09/2003, 11h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo