substr avec lettres accentuées

passant
Invité n'ayant pas de compte PHPfrance

27 oct. 2011, 12:02

Bonjour,
J'ai un souci avec les fonctions de chaines de caractères (substr, substr_replace):
exemple:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml"> 
    <head>
	<meta http-equiv="content-type" content="text/html;charset=utf-8" />
 </head>
<?PHP
   $chaine_1 = "çà";
   $longueur = strlen("ç");
   $lettre = substr($chaine_1,1); //  ne renvoie pas le à mais un zizi incompréhensible
   print "<br>la deuxième lettre de $chaine_1 est faussement $lettre<br>"; // je sais que la norme est <br />

    $lettre = substr ($chaine_1, 0+$longueur); //renvoie le à
    print "<br>la deuxième lettre de $chaine_1 est justement $lettre<br>";

    /* quand la situation se complique*/
   $chaine_2 = "tâtâmes"; 
   $chaine_3 = "tâtames";
   // il faut vérifier quelle st la lettre précédent le mes dans les deux mots en utilisant la même syntaxe
   $lettre = substr($chaine_3,-4,1);
    print "<br>la  lettre de $chaine_3 est justement $lettre<br>";
   $lettre = substr($chaine_2,-4,1);
    print "<br>la  lettre de $chaine_2 est faussement $lettre<br>";
?> 
</html>

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 oct. 2011, 12:20

salut,

problème de charset, tu utilise utf-8 et tes fonctions ne gère pas l'utf-8 il va falloir te tourner vers d'autre fonction le permettant.

pour t'aider il y un tuto de AB relatant le sujet ;)


@+
Il en faut peu pour être heureux ......

passant
Invité n'ayant pas de compte PHPfrance

27 oct. 2011, 12:59

Ca ne m'a rien appris que je ne susse déjà, et ça ne répond en rien à la question que je pose.

ViPHP
ViPHP | 3607 Messages

27 oct. 2011, 13:19

Bon on va commencer par être poli, courtois...
moogli a essayé de t'aider, si tu n'est pas prêt à recevoir de réponses autres que la solution ultime et prémachée, j'ai dans l'idée que tu n'apprendras pas grand chose sur phpfrance.com ...


Voilà tout de même de quoi t'occuper : http://php.net/manual/fr/book.mbstring.php

Mammouth du PHP | 2278 Messages

27 oct. 2011, 13:25

Bonjour,
J'ai eu un problème analogue, auquel je pensais que les fonctions mb_quelque_chose répondraient. Elles le font quand il existe l'équivalent en mb de la fonction standard, ce qui est loin d'être toujours le cas, par exemple si on veut utiliser substr_replace pour remplacer le è de évènement par un é.
On finit par y arriver à grand renfort de calculs de longeurs... (suvant qu'on remplace dans évènement ou evènement,le è ne se trouve pas à la même place, et remplacer e par é demande un paramètre nombre à remplacer de 1, quand è demande un paramètre de 2...)

C'est d'autant plus aberrant que toutes les langues sauf l'anglais, et peut-être l'italien, utilisent des caractères codés sur deux bits au lieu d'un pour les caractères standard.

Il y avait longtemps que je pensais à transformer mes chaines en tableaux, mais je me heurtais au même problème jusqu'à ce que je découvre que, si str_split ne fait pas le travail correctement sur les caractères multi_bit, mb_split suppose une regex dont je ne me souciais pas, une contribution transforme la chaine en tableau de façon très simple et très efficace.
<?php
   $string = 'Weiße Rosen sind nicht grün!' 
   $stop   = mb_strlen( $string);
  $result = array();
   for( $idx = 0; $idx < $stop; $idx++)
   {
      $result[] = mb_substr( $string, $idx, 1);
   }
?> 
A partir de là, le parcoursb du tableau se fait lettre par lettre quel qu'en soit le codage...
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
xTG
ViPHP | 7331 Messages

27 oct. 2011, 13:35

Auquel cas tu peux toujours convertir la chaîne en iso pour utiliser les fonctions de base. ;)
http://www.php.net/manual/fr/function.m ... coding.php

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 oct. 2011, 14:20

j'avoue que c'est pas toujours l'unicode et php.

je viens de tester ton code sirakawa et lorsque j'essaie d'afficher le contenu du tableau (ou même si j'utilise directement le fait qu'un chaine est un tableau et que j'essaie d'afficher l'élément actif) l'affichage merdois.
Alors qu'un simple echo $string; fonctionne ^^
<!DOCTYPE html>
<html lang="fr">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
      </head>
      <body>
<?php
  $string = 'Weiße Rosen sind nicht grün!';
  echo $string;
  echo '<br />';
  for ($i=0; $i< mb_strlen($string);$i++){
      echo 'la lettre : '.$i.' est le '. $string[$i] .'<br />';
  }
  echo '<hr />';
   $stop   = mb_strlen( $string);
   for( $idx = 0; $idx < $stop; $idx++)
    {
       $result[] = mb_substr( $string, $idx, 1);
    }
    foreach ($result as $l){
        echo $l .'<br />';
    }
    echo $string;
?>
</body>
</html>
va afficher
<!DOCTYPE html>
<html lang="fr">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8" />
      </head>
      <body>
Weiße Rosen sind nicht grün!<br />la lettre : 0 est le W<br />
la lettre : 1 est le e<br />

la lettre : 2 est le i<br />
la lettre : 3 est le �<br />
la lettre : 4 est le �<br />
la lettre : 5 est le e<br />
la lettre : 6 est le  <br />
la lettre : 7 est le R<br />
la lettre : 8 est le o<br />
la lettre : 9 est le s<br />
la lettre : 10 est le e<br />

la lettre : 11 est le n<br />
la lettre : 12 est le  <br />
la lettre : 13 est le s<br />
la lettre : 14 est le i<br />
la lettre : 15 est le n<br />
la lettre : 16 est le d<br />
la lettre : 17 est le  <br />
la lettre : 18 est le n<br />
la lettre : 19 est le i<br />

la lettre : 20 est le c<br />
la lettre : 21 est le h<br />
la lettre : 22 est le t<br />
la lettre : 23 est le  <br />
la lettre : 24 est le g<br />
la lettre : 25 est le r<br />
la lettre : 26 est le �<br />
la lettre : 27 est le �<br />
la lettre : 28 est le n<br />

la lettre : 29 est le !<br />
<hr />W<br />
e<br />
i<br />
�<br />
�<br />
e<br />
 <br />
R<br />

o<br />
s<br />
e<br />
n<br />
 <br />
s<br />
i<br />
n<br />
d<br />

 <br />
n<br />
i<br />
c<br />
h<br />
t<br />
 <br />
g<br />
r<br />

�<br />
�<br />
n<br />
!<br />
Weiße Rosen sind nicht grün!</body>
</html>
ce qui est assez perturbant :)

si l'on regarde le tuto d'AB il me manque le mb_internal_encoding("UTF-8"); au début qui résout le problème avec ton code et le rend fonctionnel.

par contre je ne comprend pas pourquoi l'affichage classique (avec echo) fonctionne avec qu'afficher les caractères un par un ne fonctionne pas (c'est, en théorie, la même chose :) ).
Ca ne m'a rien appris que je ne susse déjà, et ça ne répond en rien à la question que je pose.
j'ajouterais que ton message et ton code ne reflete en rien le fait que utilise les fonction mb_string normalement prévues à cette effet.
le doctype de ton html indique un charset utf-8 j'en ai simplement conclus que tu n'avais pas utilisé ces fonctions.
je t'ai donc donné un lien explicite sur la problématique et comme AB l'avais résolu.

enfin bon cela est dit en passant ........

oui je sais où se trouve la sortie ^^

@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 2278 Messages

27 oct. 2011, 15:30

1) oui, je me suis trompé dans le copier de la doc php. Il faut mb_internal_encoding( 'UTF-8'); Ce que je ne sais pas c'est s'il le faut dans l'appelant d'une fonction, dans la fonction appelée ou les deux.
2) J'ai relu attentivement les interventions successives:
a) il est évident que passant a une certaine connaissances du codage multi-bytes => inutile de le diriger vers un tutoriel (et non pas un tutorial, comme écrivent les anglo-ignorants) sur utf-8.
b) j'ai suivi le lien indiqué pour, dans un premier temps, le refermer aussitôt, persuadé qu'il ne répondait pas à la question. Peut-être ne l'aurais-je pas s'il avait commencé par un sommaire clair.
c) suite aux observations des ayatollahs, j'ai relu le même tutoriel pour constater que sa partie php pointait sur la partie mb-??? de la documentation san aucun commentaire.
c 1) Il est évident que le lien sur la partie mb_ de la doc aurait dû être envoyé en premier à
passat, car c'était peut-être ce qu'il cherchait.
Conclusion provisoire
1) Une fois de plus, on a le sentiment que le premier mot connu entraine une réponse automatique.
2) Sur la pédagogie
j'ai été prof, et j'ai PLUS DE 20 ans durant dépanné avec succès par téléphone , novel, msdos, windows, word et famille, antivirus et tout ce qui se présentait:
a) En général, renvoyer à la doc consiste à renvoyer à un texte qui n'a pas été compris : la bonne réponse serait avez-vous lu et COMPRIS http://bidule.machin.truc\aide.html#chose? à partir de la réponse duquel on pourrait travailler.
b) lorsqu'il s'agit d'un bout de code, si le questionneur le demande, c'est qu'il ne l'a pas trouvé:
exemple : question "faut-il un circonflexe sur le i de paraitre"; réponse "T'as qu'à lire le Grévisse."
On n'a qu'à le renvoyer au Grévisse, voire lui dire "OUI" sauf s'il respecte la dernière réforme dont on fournit le lien.
Imaginez un de vos profs, ayant souligné une faute dans votre production, vous disant "T'as qu'à lire mon cours".


Je croyais que phpfrance était animé par des humains, je me convaincs de jour en jour qu'il s'agit de robots mal programmés, ou de
mots clés mal définis...
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 oct. 2011, 16:06

je vais mas répondre a tout :

- le message original n'indique nul part une quelconque utilisation des fonctions de l'extension mbstring
- ma réponse indique une "ressource" permettant une première approche (certain simpliste mais elle a le mérite d'exister)
- Ayant moi aussi fait du support technique sur du matériel précis pour des professionnels je peux assurer que certain essai de monter une télégestion complète avec un tournevis et une boite de boulon sans lire la doc !
- La réponse n'est pas forcément automatique, j'ai déjà expliqué la démarche m'ayant amené à indiquer ce lien.
- j'ai eu un prof d'électronique qui au premier TP sur un soft sous pour tracer mon pcb (pads) m'a répondu : c'est pas mon problème à la première question que je lui posé sur le soft (après plusieurs jours d'utilisation sans problème). effectivment j'ai trouvé la solution dans une doc volumineuse avec l'aide de 2 - 3 copains.
- pour ce qui est de ton N°1 ce n'est pas un reproche je ne savais pas non plus, n'ayant jamais eu a utiliser mbstring.
- quand à l'évidence de ces connaissances moi je n'ai pas étant donnée le premier message, le second n'étant qu'un tacle n'apportant pas de précision (ou mon lave vaisselle lave la vaisselle ...... des fois).
- si la doc n'a pas été comprise autant le dire directement c'est pas une tare.

Bref au final j'aurais mieux de mettre en gros

pour répondre à une question il faut :
- que celle ci soit au moins formulée
- des exemples de ce qui a été fait
- une explication concrète de ce que l'on veux


le premier point est absent du message d'origine
- le second existe effectivement, les commentaire indique certaine chose (heureusement sinon la réponse aurait pu être "et alors ?").
- le trois ben y a pas non plus, même si en décortiquant le code on à une idée

Bref on pourrais encore faire quelques centaines de messages sur le sujet mais ça ne changerais rien.
Je croyais que phpfrance était animé par des humains, je me convaincs de jour en jour qu'il s'agit de robots mal programmés, ou de mots clés mal définis...
oui des humains, qui font cela bénévolement, et qui répondent régulièrement aux mêmes questions tout le temps (je pense que tu l'a certainement remarqué).
Des humains qui voient des messages suivis de 5000 réponses et se rendent compte qu'au final l'auteur d'origine n'a pas compris une fonction simple, ou tout simplement n'a pas posé la bonne question et que donc on ne pouvait que répondre à coté de la plaque.
Des humains qui au final se rendent compte que les réponses les plus basiques sont parfois les bonnes.
Des humains qui, parfois, se creuse la cervelle pour comprendre ce qu'il y a dans celle des autres et leurs répondre.
Des humains, qui comme toi, on parfois des idées toute faite et font l'impasse sur certain truc (cas de la lecture du 1er lien que tu indique)

au final j'ai donné une solution qui me semblais et me semble toujours cohérente au vu problème posé, qui n'est ni complet ni même une question.

Le minimum aurait été simplement d'indiquer qu'il avait déjà vu la chose, quels test avait fait et quel en était les résultats.

Et je rappellerais que les gens qui ne sont pas satisfait peuvent :
- prendre des cours
- aller voir ailleurs !

@+
Il en faut peu pour être heureux ......

Mammouth du PHP | 2278 Messages

27 oct. 2011, 16:49

En clair, les animateurs de Phpfrance ont TOUJOURS raison même quand ils ont tort, qu'on se le dise.
rappel de la bible du bizu th:
Le bizuth n'a qu'undoit: celui de se taire.
Il a un deuxième droit: celui d'abuser du premier.

Je répète que, trop souvent, les réponses montrent une lecture superficielle de la question posée.
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

ViPHP
ViPHP | 2577 Messages

27 oct. 2011, 16:51

Bonjour,

Le problème peut se résumer cette ligne trouvée dans le lien :
- strpos(), strlen(), substr() etc. => utilisez les fonctions adaptées au traitement des chaines UTF-8
Il me semble intéressant de voir le pourquoi le problème et la solution que sont les fonctions mb_X

Dans mon cas je ne connaissais que vaguement le problème du codage sur plusieurs caractères. La question portant sur l'usage de la fonction substr(), il n'est pas surprenant de supposer qu'un lien est vers cette problématique soit proposée.

Sur les pratiques, je suis la pour voir les problèmes des autres et apprendre des choses en cherchant des solutions. Le plus souvent, une recherche via google ou directement sur php.net me fournit la solution. Je fais ca si le problème m'intéresse, mais ca ne m'empêche pas de penser qu'une petite recherche par l'auteur du post aurait donné le même résultat. Ma première réponse est souvent une réponse sommaire donnant une piste mais qui me semble suffisante. A la limite un nom de fonction avec le lien sur php.net ; il est possible qu'une fonction échappe à quelqu'un et la doc est suffisant. En tout cas, c'est une réponse qui me semblerait bien quitte à demander des explications complémentaires. J'évite généralement d'intervenir sur les sujets qui font plus d'une page par expérience.

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

27 oct. 2011, 17:26

En clair, les animateurs de Phpfrance ont TOUJOURS raison même quand ils ont tort, qu'on se le dise.
rappel de la bible du bizu th:
Le bizuth n'a qu'undoit: celui de se taire.
Il a un deuxième droit: celui d'abuser du premier.

Je répète que, trop souvent, les réponses montrent une lecture superficielle de la question posée.
je te propose une chose : prend tout les sujet et répond à la problèmatique posé en une seule fois de manière claire, simple, précises, sans donner la solution pré mâché (tout en ayant la chose dans la tête). je ne suis pas certain que tu y arrive.
On peu le faire par expérience sur certain question, mais ça reste des cas isolé !

quand aux animateurs de phpfrance, je vais être clair : je ne suis rien, phpfrance existait avant moi et existera surement après. Le rond violet n'indique pas que j'ai plus de poids que les autres, juste que d'autre on jugé que ça pouvais faire bien à coté de mes messages.

Comme Mazarini j'essaie de répondre aux questions pour aider, et souvent pour apprendre des difficultés des autres.

Maintenant tous ceci n'apporte strictement rien au sujet de départ, vu que l'auteur s'en fou (je pense) et n'a pas apporté plus d'info.

Je vois ma participation comme une aide et non un service. si quelqu'un me demande de lui faire son code pourquoi pas mais va falloir qui aligne les chiffres avant que je code !

voila voila bientôt la seconde page et les 2500 messages :twisted:
Il en faut peu pour être heureux ......