Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

unicode (?), regexp, SQL... le bordel

9 views
Skip to first unread message

Olivier Masson

unread,
Oct 16, 2009, 9:40:29 AM10/16/09
to
Bonjour,

J'ai du mal � comprendre et surtout � r�soudre un probl�me tout b�te.

Je cherche � parser un texte � la recherche d'expressions pr�sentes dans
une base. Ce que font les tonnes des trucs � la autolink.

Mais, si tout va bien dans mes tests hors SQL, si tout va bien sur la
pluparts des mots et expressions, �a foire avec les quotes.

Ceci place des % entre les expressions ($exp) trouv�es dans la base MySQL :
preg_replace ( "#(\W)(" . preg_quote ( $exp ) . ")(\W)#Ui" ,
'${1}%${2}%${3}' , $texte , $max );

Si, au sein du script php, je cherche "aujourd'hui", �a ne fonctionne pas.
Normal, le probl�me est que le texte original transforme les ' en ' (je
ne le contr�le pas).
Donc, toujours au sein du script, je cherche "aujourd'hui" et l�, �a
fonctionne.

Par contre, quand j'utilise la sortie MySQL, �a ne fonctionne plus. J'ai
beau faire un str_replace("'","'",$texte) ou un
str_replace("'","'",$exp), �a ne fonctionne pas du moment que $exp vient
de la base de donn�es.

Pourtant, quand je fais un echo du $exp sorti de la base et que je fais
un copier/coller dans le script, �a fonctionne.

Tout est cens� �tre en utf-8 et j'ai m�me insist� avec un
set_charset('utf8') pour la connexion MySQL.

Alors bon, j'en ai marre :(

Olivier Miakinen

unread,
Oct 16, 2009, 9:46:54 AM10/16/09
to
[Publication en UTF-8]

Bonjour,

Le 16/10/2009 15:40, Olivier Masson a écrit :
>
> [...] je cherche "aujourd'hui", ça ne fonctionne pas.
>
> [...] transforme les ' en ' [...]
>
> [...] je cherche "aujourd'hui" et là, ça fonctionne.
>
> [...] str_replace("'","'",$texte) [...]

Tu devrais republier ton article en UTF-8 plutôt qu'en Windows-1252, il
y a moins de risques que les ’ se transforment en ', rendant ta question
incompréhensible.

Cordialement,
--
Olivier Miakinen

Olivier Masson

unread,
Oct 16, 2009, 10:34:56 AM10/16/09
to
Olivier Miakinen a écrit :

> Tu devrais republier ton article en UTF-8 plutôt qu'en Windows-1252, il
> y a moins de risques que les ’ se transforment en ', rendant ta question
> incompréhensible.
>
> Cordialement,

/ Merci Olivier, je pensais que Tb faisait ça comme un grand (d'ailleurs
c'est iso-8859-1 qui est choisi dans ma conf, pas windows-1252 : pas
bien Tb !)
Je reprends donc : /

Bonjour,

J'ai du mal à comprendre et surtout à résoudre un problème tout bête.

Je cherche à parser un texte à la recherche d'expressions présentes dans
une base. Ce que font les tonnes des trucs à la autolink.

Mais, si tout va bien dans mes tests hors SQL, si tout va bien sur la

pluparts des mots et expressions, ça foire avec les quotes.

Ceci place des % entre les expressions ($exp) trouvées dans la base MySQL :


preg_replace ( "#(\W)(" . preg_quote ( $exp ) . ")(\W)#Ui" ,
'${1}%${2}%${3}' , $texte , $max );

Si, au sein du script php, je cherche "aujourd'hui", ça ne fonctionne pas.
Normal, le problème est que le texte original transforme les ' en ’ (je
ne le contrôle pas).
Donc, toujours au sein du script, je cherche "aujourd’hui" et là, ça
fonctionne.

Par contre, quand j'utilise la sortie MySQL, ça ne fonctionne plus. J'ai


beau faire un str_replace("’","'",$texte) ou un

str_replace("'","’",$exp), ça ne fonctionne pas du moment que $exp vient
de la base de données.

Pourtant, quand je fais un echo du $exp sorti de la base et que je fais

un copier/coller dans le script, ça fonctionne.

Tout est censé être en utf-8 et j'ai même insisté avec un
set_charset('utf8') pour la connexion MySQL (j'ai aussi forcé avec un
iconv sans résultat).


Alors bon, j'en ai + que marre :(


PS : pourquoi les mb_ utilisent les regex POSIX (y'a pas de mb_ereg)
alors qu'elles sont dépréciées ?

Olivier Miakinen

unread,
Oct 16, 2009, 10:34:56 AM10/16/09
to
En attendant ta republication, quelques remarques quand mᅵme :

Le 16/10/2009 15:40, Olivier Masson a ᅵcrit :
>
> Ceci place des % entre les expressions ($exp) trouvᅵes dans la base MySQL :


> preg_replace ( "#(\W)(" . preg_quote ( $exp ) . ")(\W)#Ui" ,
> '${1}%${2}%${3}' , $texte , $max );

Tout d'abord, si les expressions $exp sont censᅵes toujours commencer et
finir par un caractᅵre ᅵ de mot ᅵ, alors une assertion ᅵ limite de mot ᅵ
est plus facile ᅵ lire qu'un (\W) repris dans un ${1}. Qui plus est,
cela fonctionnera mᅵme en dᅵbut de chaᅵne, ce qui n'est pas le cas avec
(\W).

preg_replace ( "#\b(" . preg_quote ( $exp ) . ")\b#Ui" , '%${1}%' ,
$texte , $max );

Personnellement j'ai l'habitude de respecter ᅵ peu prᅵs la typographie
en ce qui concerne les espaces ᅵ l'intᅵrieur des parenthᅵses et avant
les virgules, d'autant que c'est la mᅵme en anglais et en franᅵais, mais
tu n'es bien sᅵr pas obligᅵ de penser comme moi. Malgrᅵ tout je le fais
ici pour ᅵtre sᅵr de ne rien oublier d'autre. Je supprime en gᅵnᅵral
aussi l'espace entre le nom d'une fonction et sa parenthᅵse ouvrante, et
je prᅵfᅵre utiliser $1 plutᅵt que ${1} (sauf bien sᅵr s'il est suivi
d'un chiffre, ce qui ne m'est jamais arrivᅵ).

preg_replace("#\b(" . preg_quote($exp) . ")\b#Ui", '%$1%',
$texte, $max);

Tiens, je m'aperᅵois que tous les caractᅵres servant au ᅵ matching ᅵ
sont utilisᅵs, on peut donc encore ᅵconomiser deux parenthᅵses et
(selon moi, mais c'est trᅵs subjectif) amᅵliorer encore la lisibilitᅵ.

preg_replace("#\b" . preg_quote($exp) . "\b#Ui", '%$0%',
$texte, $max);

Maintenant, puisque tu dis que tout est en UTF-8, je pense que l'option
ᅵ u ᅵ (PCRE8) s'impose, d'autant que tu n'utilises aucune fonction
spᅵcifique ᅵ PCRE. Si ᅵa se trouve, c'est la seule source de tes soucis,
mᅵme si je n'en ai aucune idᅵe parce que je n'ai pas encore vraiment
compris le problᅵme.

preg_replace("#\b" . preg_quote($exp) . "\b#Uiu", '%$0%',
$texte, $max);

Voilᅵ. Pour le reste on verra plus tard...

Olivier Miakinen

unread,
Oct 16, 2009, 10:57:57 AM10/16/09
to
Le 16/10/2009 16:34, Olivier Masson a écrit :
>
<HS>

>> Tu devrais republier ton article en UTF-8 plutôt qu'en Windows-1252, il
>> y a moins de risques que les ’ se transforment en ', rendant ta question
>> incompréhensible.
>>
>> Cordialement,
>
> / Merci Olivier, je pensais que Tb faisait ça comme un grand (d'ailleurs
> c'est iso-8859-1 qui est choisi dans ma conf, pas windows-1252 : pas
> bien Tb !)

Je pense que c'est intl.fallbackCharsetList.ISO-8859-1 qui vaut
windows-1252 par défaut et qu'il faut changer pour autre chose.

Tu peux y mettre UTF-8, mais personnellement j'y ai mis ISO-8859-15 et
ça marche très bien : Thunderbird choisit tout seul entre ISO-8859-1 et
ISO-8859-15 quand il le peut, et sinon il me demande de confirmer le
passage à UTF-8.
</HS>

> Je reprends donc : /
>
> [...]


>
> Ceci place des % entre les expressions ($exp) trouvées dans la base MySQL :
> preg_replace ( "#(\W)(" . preg_quote ( $exp ) . ")(\W)#Ui" ,
> '${1}%${2}%${3}' , $texte , $max );

Tiens, j'ai oublié de te signaler un truc dans mon article précédent :
remplacer preg_quote($exp) par preg_quote($exp, '#') au cas où tu
pourrais trouver un '#' dans $exp !

> Si, au sein du script php, je cherche "aujourd'hui", ça ne fonctionne pas.
> Normal, le problème est que le texte original transforme les ' en ’ (je
> ne le contrôle pas).
> Donc, toujours au sein du script, je cherche "aujourd’hui" et là, ça
> fonctionne.
>
> Par contre, quand j'utilise la sortie MySQL, ça ne fonctionne plus. J'ai
> beau faire un str_replace("’","'",$texte) ou un
> str_replace("'","’",$exp), ça ne fonctionne pas du moment que $exp vient
> de la base de données.

Pour comprendre ce qui se passe réellement, il serait intéressant
d'avoir un « dump » hexadécimal du $exp et de $texte. Est-ce que
des caractères Unicode ne seraient pas ajoutés automatiquement quand
on rencontre un « ’ » ?

> Pourtant, quand je fais un echo du $exp sorti de la base et que je fais
> un copier/coller dans le script, ça fonctionne.

Idem. Si le copier/coller ne recopie pas un caractère invisible du style
d'un BOM, cela pourrait peut-être expliquer le comportement.

> PS : pourquoi les mb_ utilisent les regex POSIX (y'a pas de mb_[p]reg)

> alors qu'elles sont dépréciées ?

Problablement parce que tout le monde se fout des fonctions mb_*, vu que
le vrai standard est UTF-8 et que les fonctions preg_* savent très bien
les gérer avec l'option u ?

Olivier Masson

unread,
Oct 16, 2009, 12:37:19 PM10/16/09
to
Olivier Miakinen a écrit :

>
> preg_replace("#\b" . preg_quote($exp) . "\b#Ui", '%$0%',
> $texte, $max);
>

Pour les espaces, je fais comme toi mais là, j'éclaircis à force de
modifications.
Oui, pour le \b ça doit fonctionner mais j'ai déjà rencontré des
problèmes avec son utilisation (surement de ma faute).
Et pour # dans preg_quote, il y est à l'origine, mais merci.

> Maintenant, puisque tu dis que tout est en UTF-8, je pense que l'option

> « u » (PCRE8) s'impose, d'autant que tu n'utilises aucune fonction
> spécifique à PCRE. Si ça se trouve, c'est la seule source de tes soucis,
> même si je n'en ai aucune idée parce que je n'ai pas encore vraiment
> compris le problème.


>
> preg_replace("#\b" . preg_quote($exp) . "\b#Uiu", '%$0%',
> $texte, $max);
>

Ben écoute, au moins j'aurais appris un truc car je n'avais jamais prêté
attention à l'option u ! Ca va m'alléger quelques scripts.

Pour mon problème, ça ne change rien. Ce que j'ai du mal à comprendre,
c'est qu'en fait, le quote, ce serait un /x92, typique de CP1252 alors
que c'est de l'utf-8 partout.
Lorsque je fais str_replace("’","'",$texte), le texte n'est pas modifié.
Par contre l'opération inverse sur $exp fonctionne (' se transforme bien
en ’).
Pourtant, à l'écran, ces deux ’ sont les mêmes. Y'a-t-il
translittération automatique qq part ?

Démonstration (en espérant que tout passe tel quel) :
iconv('Windows-1252' ,'UTF-8', $exp) : aujourd’hui
iconv('Windows-1252' ,'UTF-8', $texte) : aujourd’hui
iconv('UTF-8' ,'Windows-1252', $exp) : aujourd�hui
iconv('UTF-8' ,'Windows-1252', $texte) : aujourd’hui
iconv('iso-8859-1' ,'UTF-8', $exp) : aujourd’hui€™ (là, le cc ne
fonctionne pas)
iconv('iso-8859-1' ,'UTF-8', $texte) : aujourd’hui

J'en déduis bêtement que mon $exp est bien en utf-8 et mon $texte non.
Alors que la base et le champ sont en utf-8 et que mb_detect_encoding me
dit qu'il s'agit d'utf-8.

Où je deviens fou, c'est qu'en faisant :
str_replace("'",chr(146),$exp)
pour remplacer le ' de ma base par un \x92 bien moche qui est censé être
dans le texte, bien évidemment, ça ne fonctionne pas et ne s'affiche
même pas puisque chr(146) en utf-8, ça plait pas.

Pour finir, j'ai essayé un
str_replace("'","&#8217;",$exp), ce qui a bien remplacé le ' par un ’...
mais toujours pas considéré comme identique à celui du $texte.

Olivier Miakinen

unread,
Oct 16, 2009, 1:12:17 PM10/16/09
to
Le 16/10/2009 18:37, Olivier Masson a écrit :
>
> Pour mon problème, ça ne change rien. Ce que j'ai du mal à comprendre,
> c'est qu'en fait, le quote, ce serait un /x92, typique de CP1252 alors
> que c'est de l'utf-8 partout.

Ah, on avance.

> Lorsque je fais str_replace("’","'",$texte), le texte n'est pas modifié.
> Par contre l'opération inverse sur $exp fonctionne (' se transforme bien
> en ’).
> Pourtant, à l'écran, ces deux ’ sont les mêmes. Y'a-t-il
> translittération automatique qq part ?
>
> Démonstration (en espérant que tout passe tel quel) :
> iconv('Windows-1252' ,'UTF-8', $exp) : aujourd’hui

’ : E2 80 99, si le charset était Windows-1252. Puisque c'est le
résultat de iconv('Windows-1252', 'UTF-8'), on peut supposer que
$exp contient bien une apostrophe UTF-8 à l'origine.

> iconv('Windows-1252' ,'UTF-8', $texte) : aujourd’hui

Du coup, on peut supposer que $texte contient une apostrophe
Windows-1252 à l'origine.

> iconv('UTF-8' ,'Windows-1252', $exp) : aujourd�hui

Logique : il transforme une apostrophe UTF-8 en Windows-1252, et le
résultat n'est pas de l'UTF-8.

> iconv('UTF-8' ,'Windows-1252', $texte) : aujourd’hui

Ah zut, là je ne comprends pas comment c'est possible.

> iconv('iso-8859-1' ,'UTF-8', $exp) : aujourd’hui€™ (là, le cc ne
> fonctionne pas)

Ça, cela reste logique : des trois codes \xE2, \x80 et \x99 d'origine,
seul le \xE2 existe en Latin1 ; les autres sont virés.

> iconv('iso-8859-1' ,'UTF-8', $texte) : aujourd’hui

Hum...

> J'en déduis bêtement que mon $exp est bien en utf-8 et mon $texte non.

Je ne te demande que deux tests :
bin2hex($exp)
bin2hex($texte)
Là on saura enfin ce qu'ils ont dans le ventre.

> Alors que la base et le champ sont en utf-8 et que mb_detect_encoding me
> dit qu'il s'agit d'utf-8.

Une possibilité serait que l'apostrophe Windows-1252 ait été encodée en
UTF-8 *comme si* c'était du Latin1, ce qui donnerait C2 92 au lieu de
92 (Windows-1252 vrai) ou de E2 80 99 (UTF-8 vrai). Je pense que la
fonction utf8_encode doit faire ce genre de blague.

> Où je deviens fou, c'est qu'en faisant :
> str_replace("'",chr(146),$exp)
> pour remplacer le ' de ma base par un \x92 bien moche qui est censé être
> dans le texte, bien évidemment, ça ne fonctionne pas et ne s'affiche
> même pas puisque chr(146) en utf-8, ça plait pas.

et str_replace("'", "\xC2\x99", $exp) ?

> Pour finir, j'ai essayé un
> str_replace("'","&#8217;",$exp), ce qui a bien remplacé le ' par un ’...
> mais toujours pas considéré comme identique à celui du $texte.

Oui, ça c'est normal. Ce sont deux représentations complètement différentes.

Cordialement,
--
Olivier Miakinen

Olivier Masson

unread,
Oct 16, 2009, 2:23:38 PM10/16/09
to
Olivier Miakinen a écrit :

> Je ne te demande que deux tests :
> bin2hex($exp)
> bin2hex($texte)
> Là on saura enfin ce qu'ils ont dans le ventre.
>

Ah ben c'est sûr...
version base : 7465737420696369
version texte : 3c703e61756a6f7572642623383231373b6875693c2f703e0a
Au cas où, je signale que les accents, que ce soit dans la base ou le
texte passe très bien sur la page résultante encodée en utf-8.

> et str_replace("'", "\xC2\x99", $exp) ?
>

Gros caca à la place du '

Olivier Miakinen

unread,
Oct 16, 2009, 2:31:03 PM10/16/09
to
Le 16/10/2009 20:23, Olivier Masson a ᅵcrit :

>
>> Je ne te demande que deux tests :
>> bin2hex($exp)
>> bin2hex($texte)
>> Lᅵ on saura enfin ce qu'ils ont dans le ventre.
>
> Ah ben c'est sᅵr...
> version base : 7465737420696369

"test ici" ;-)

> version texte : 3c703e61756a6f7572642623383231373b6875693c2f703e0a

"<p>aujourd&#8217;hui</p>"

Ah, je comprends mieux pourquoi toutes les versions marchaient, quels
que soient les iconv() effectuᅵs ! Il n'y a que de l'ASCII ici, et c'est
juste ᅵ l'affichage que tu montres une apostrophe...

Olivier Miakinen

unread,
Oct 16, 2009, 3:09:44 PM10/16/09
to
Le 16/10/2009 20:23, Olivier Masson a ᅵcrit :
>
>> bin2hex($exp)
>> bin2hex($texte)

>
> version base : 7465737420696369
> version texte : 3c703e61756a6f7572642623383231373b6875693c2f703e0a


Pour la prochaine fois, plutᅵt qu'un simple bin2hex($exp) dont le
rᅵsultat est un peu trop compact, je te suggᅵre :
chunk_split(bin2hex($exp), 2, " ");

Olivier Masson

unread,
Oct 17, 2009, 3:56:22 PM10/17/09
to
Olivier Miakinen a ᅵcrit :

> Le 16/10/2009 20:23, Olivier Masson a ᅵcrit :
>>> Je ne te demande que deux tests :
>>> bin2hex($exp)
>>> bin2hex($texte)
>>> Lᅵ on saura enfin ce qu'ils ont dans le ventre.
>> Ah ben c'est sᅵr...
>> version base : 7465737420696369
>
> "test ici" ;-)
>

:) je ne parle pas hexadecimal couramment, me suis plantᅵ de ligne.

61 75 6a 6f 75 72 64 27 68 75 69
61 75 6a 6f 75 72 64 26 23 38 32 31 37 3b 68 75 69

>> version texte : 3c703e61756a6f7572642623383231373b6875693c2f703e0a
>
> "<p>aujourd&#8217;hui</p>"
>
> Ah, je comprends mieux pourquoi toutes les versions marchaient, quels
> que soient les iconv() effectuᅵs ! Il n'y a que de l'ASCII ici, et c'est
> juste ᅵ l'affichage que tu montres une apostrophe...

Mais pourquoi cette entitᅵ n'apparait nulle part (dans le code) ?

Olivier Miakinen

unread,
Oct 17, 2009, 5:23:07 PM10/17/09
to
Le 17/10/2009 21:56, Olivier Masson a ᅵcrit :

>
> 61 75 6a 6f 75 72 64 27 68 75 69

aujourd'hui

> 61 75 6a 6f 75 72 64 26 23 38 32 31 37 3b 68 75 69

aujourd&#8217;hui

Bon sang, mais c'est bien sᅵr ! Parmi toutes les modifications que
j'aurais faites ᅵ ta ligne de code, il y en a une dont je n'ai pas
parlᅵ, c'est que je trouvais le caractᅵre ᅵ # ᅵ peu lisible comme
dᅵlimiteur d'expression rationnelle ; je n'en ai pas parlᅵ car encore
une fois la lisibilitᅵ est quelque chose de subjectif. Mais ici, il
n'est pas question que de lisibilitᅵ : tu as un ᅵ # ᅵ dans la chaᅵne
elle-mᅵme ! Ah, sauf que tu dis que tu le passes bien en paramᅵtre ?
Bon, eh bien je n'en sais rien.

>>> version texte : 3c703e61756a6f7572642623383231373b6875693c2f703e0a
>>
>> "<p>aujourd&#8217;hui</p>"
>>
>> Ah, je comprends mieux pourquoi toutes les versions marchaient, quels
>> que soient les iconv() effectuᅵs ! Il n'y a que de l'ASCII ici, et c'est
>> juste ᅵ l'affichage que tu montres une apostrophe...
>
> Mais pourquoi cette entitᅵ n'apparait nulle part (dans le code) ?

ᅵa, c'est ᅵ toi de nous le dire car tu es le seul ᅵ l'avoir, le code.
Sans infos supplᅵmentaires, j'ai mᅵme cru que c'ᅵtait bien dans le code
et que tu avais oubliᅵ de faire ᅵ View > Source ᅵ sur la page HTML.

--
Olivier Miakinen

Olivier Masson

unread,
Oct 18, 2009, 3:01:41 PM10/18/09
to
Olivier Miakinen a ᅵcrit :
> Le 17/10/2009 21:56, Olivier Masson a ᅵcrit :
>> 61 75 6a 6f 75 72 64 27 68 75 69
>
> aujourd'hui
>
>> 61 75 6a 6f 75 72 64 26 23 38 32 31 37 3b 68 75 69
>
> aujourd&#8217;hui
>
> Bon sang, mais c'est bien sᅵr ! Parmi toutes les modifications que
> j'aurais faites ᅵ ta ligne de code, il y en a une dont je n'ai pas
> parlᅵ, c'est que je trouvais le caractᅵre ᅵ # ᅵ peu lisible comme
> dᅵlimiteur d'expression rationnelle ; je n'en ai pas parlᅵ car encore
> une fois la lisibilitᅵ est quelque chose de subjectif. Mais ici, il
> n'est pas question que de lisibilitᅵ : tu as un ᅵ # ᅵ dans la chaᅵne
> elle-mᅵme ! Ah, sauf que tu dis que tu le passes bien en paramᅵtre ?
> Bon, eh bien je n'en sais rien.

ᅵ'aurait effectivement pu ᅵtre la bonne solution, pas ᅵvidente ᅵ trouver.
En fait, je viens ᅵ l'instant de voir une erreur que j'avais faite.
Comme je ne peux pas modifier ce qui vient de $texte, j'ai voulu
modifier ce qui provenait de la base. Et lᅵ, je ne comprenais vraiment
pas pourquoi ᅵa ne fonctionnait pas. Et puis avec ta trᅵs bonne idᅵe du
binhex, ᅵa devenait plus facile ᅵ voir.
Je faisais (depuis tes infos sur cet ᅵtrange &#8217) :
str_replace("'", "&#8217",$exp);

Ben oui, c'est bᅵta hein :) Il manquait juste le ;.
Donc maintenant ᅵa fonctionne !

Merci beaucoup pour ton aide.

Olivier Miakinen

unread,
Oct 18, 2009, 3:45:51 PM10/18/09
to
Le 18/10/2009 21:01, Olivier Masson a écrit :
>
> [...]
> Je faisais (depuis tes infos sur cet étrange &#8217) :
> str_replace("'", "&#8217",$exp);
>
> Ben oui, c'est béta hein :) Il manquait juste le ;.
> Donc maintenant ça fonctionne !

D'autant plus béta que dans <4ad89fed$0$10119$426a...@news.free.fr>
tu avais bien écrit :
<cit.>


Pour finir, j'ai essayé un
str_replace("'","&#8217;",$exp), ce qui a bien remplacé le ' par un ’...

</cit.>
... ce qui fait que je n'ai pas pu le corriger ici.

> Merci beaucoup pour ton aide.

Avec plaisir.

--
Olivier Miakinen

Olivier Masson

unread,
Oct 24, 2009, 6:16:54 AM10/24/09
to
Olivier Miakinen a ᅵcrit :
> En attendant ta republication, quelques remarques quand mᅵme :
>
> Le 16/10/2009 15:40, Olivier Masson a ᅵcrit :
>> Ceci place des % entre les expressions ($exp) trouvᅵes dans la base MySQL :
>> preg_replace ( "#(\W)(" . preg_quote ( $exp ) . ")(\W)#Ui" ,
>> '${1}%${2}%${3}' , $texte , $max );
>
> Tout d'abord, si les expressions $exp sont censᅵes toujours commencer et
> finir par un caractᅵre ᅵ de mot ᅵ, alors une assertion ᅵ limite de mot ᅵ
> est plus facile ᅵ lire qu'un (\W) repris dans un ${1}. Qui plus est,
> cela fonctionnera mᅵme en dᅵbut de chaᅵne, ce qui n'est pas le cas avec
> (\W).
>
> preg_replace ( "#\b(" . preg_quote ( $exp ) . ")\b#Ui" , '%${1}%' ,
> $texte , $max );
>

En fait, ᅵa ne fonctionne pas avec /b car il n'isole pas "isoloir" dans
"l'isoloir".

Olivier Miakinen

unread,
Oct 24, 2009, 7:54:17 AM10/24/09
to
Le 24/10/2009 12:16, Olivier Masson a ᅵcrit :

>>
>>> preg_replace ( "#(\W)(" . preg_quote ( $exp ) . ")(\W)#Ui" ,
>>> '${1}%${2}%${3}' , $texte , $max );
>>
>> Tout d'abord, si les expressions $exp sont censᅵes toujours commencer et
>> finir par un caractᅵre ᅵ de mot ᅵ, alors une assertion ᅵ limite de mot ᅵ
>> est plus facile ᅵ lire qu'un (\W) repris dans un ${1}. Qui plus est,
>> cela fonctionnera mᅵme en dᅵbut de chaᅵne, ce qui n'est pas le cas avec
>> (\W).
>>
>> preg_replace ( "#\b(" . preg_quote ( $exp ) . ")\b#Ui" , '%${1}%' ,
>> $texte , $max );
>
> En fait, ᅵa ne fonctionne pas avec /b

\b

> car il n'isole pas "isoloir" dans "l'isoloir".

Hein ? Alors ᅵ ' ᅵ fait partie de \W, ᅵ i ᅵ de \w, mais le \b ne matche
pas au milieu de ᅵ 'i ᅵ ??? Je viens de faire des tests, et pour moi ᅵa
marche -- conformᅵment ᅵ la doc.

--
Olivier Miakinen

Olivier Masson

unread,
Oct 24, 2009, 3:12:32 PM10/24/09
to
Olivier Miakinen a ᅵcrit :

> Hein ? Alors ᅵ ' ᅵ fait partie de \W, ᅵ i ᅵ de \w, mais le \b ne matche


> pas au milieu de ᅵ 'i ᅵ ??? Je viens de faire des tests, et pour moi ᅵa
> marche -- conformᅵment ᅵ la doc.
>

Je retire, jma trompᅵ !
C'est plus tordu : sur mon serveur en local, tout fonctionne. Par
contre, sur un serveur Amen (oui, je sais, c'est mauvais, mais ce n'est
pas le mien), ᅵa ne fonctionne pas. Pas ᅵ cause de l'apostrophe comme je
l'ai cru mais ᅵ cause de l'accent.

Donc l'exemple avec l'isoloir, on oublie, j'ai fait n'importe quoi.
Par contre, sur le serveur Amen, "ᅵtude" n'ᅵtait pas trouvᅵ.
J'ai donc comparᅵ avec bin2hex mais cette fois, le problᅵme ne venait
pas des chaines.
C'est bel et bien le preg-replace qui ne fonctionnait pas.

Je t'avais dit que j'avais dᅵjᅵ rencontrᅵ des problᅵmes avec \b. ᅵa n'a
pas loupᅵ : j'y ai encore une fois eu le droit.
Tout fonctionne avec \W.

Par contre pourquoi, ᅵa, aucune idᅵe. Pas eu le tps de tester sur un
serveur linux ᅵ moi.

Olivier Miakinen

unread,
Oct 24, 2009, 4:19:04 PM10/24/09
to
Le 24/10/2009 21:12, Olivier Masson a ᅵcrit :

>
> Je retire, jma trompᅵ !
> C'est plus tordu : sur mon serveur en local, tout fonctionne. Par
> contre, sur un serveur Amen (oui, je sais, c'est mauvais, mais ce n'est
> pas le mien), ᅵa ne fonctionne pas. Pas ᅵ cause de l'apostrophe comme je
> l'ai cru mais ᅵ cause de l'accent.
>
> [...] sur le serveur Amen, "ᅵtude" n'ᅵtait pas trouvᅵ.

Bon sang mais c'est bien sᅵr ! Et pour le coup c'est Amen qui a raison,
en utilisant problablement une locale "C" alors qu'en local tu dois ᅵtre
en franᅵais. Tu dois avoir parfois des comportements assez inattendus
sur ton serveur local.

> [...]


> Je t'avais dit que j'avais dᅵjᅵ rencontrᅵ des problᅵmes avec \b. ᅵa n'a
> pas loupᅵ : j'y ai encore une fois eu le droit.
> Tout fonctionne avec \W.

Oui, mais ᅵa ne marchera pas dans tous les cas. Par exemple, si tu
cherches ᅵ change ᅵ il le trouvera dans ᅵ ᅵchange ᅵ, et si tu cherches
ᅵ coup ᅵ il le trouvera dans ᅵ dᅵcoupᅵt ᅵ.

> Par contre pourquoi, ᅵa, aucune idᅵe. Pas eu le tps de tester sur un
> serveur linux ᅵ moi.

La raison est trᅵs simple. Avec une locale franᅵaise, ᅵ ᅵ ᅵ et ᅵ ᅵ ᅵ
font partie de \w alors qu'avec la locale "C" ils font partie de \W.

Du coup, puisque tes chaᅵnes sont en UTF-8 je te suggᅵre d'utiliser des
assertions, avec la propriᅵtᅵ Unicode \P{L} ou \PL qui signifie ᅵ n'est
pas une lettre ᅵ (quelle que soit la langue) :

preg_replace("/(?<=\PL)" . preg_quote($exp) . "(?=\PL)/Uiu",
'%$0%', $texte, $max);

Voire, pour gᅵrer le cas du dᅵbut ou de la fin de texte :

preg_replace("/(?<=^|\PL)" . preg_quote($exp) . "(?=\PL|$)/Uiu",
'%$0%', $texte, $max);

http://fr.php.net/manual/fr/regexp.reference.assertions.php
http://fr.php.net/manual/fr/regexp.reference.circudollar.php
http://fr.php.net/manual/fr/regexp.reference.unicode.php

--
Olivier Miakinen

Olivier Masson

unread,
Oct 26, 2009, 12:08:30 PM10/26/09
to
Olivier Miakinen a ᅵcrit :

> Bon sang mais c'est bien sᅵr ! Et pour le coup c'est Amen qui a raison,

Ah merde !


> Du coup, puisque tes chaᅵnes sont en UTF-8 je te suggᅵre d'utiliser des
> assertions, avec la propriᅵtᅵ Unicode \P{L} ou \PL qui signifie ᅵ n'est
> pas une lettre ᅵ (quelle que soit la langue) :
>
> preg_replace("/(?<=\PL)" . preg_quote($exp) . "(?=\PL)/Uiu",
> '%$0%', $texte, $max);
>
> Voire, pour gᅵrer le cas du dᅵbut ou de la fin de texte :
>
> preg_replace("/(?<=^|\PL)" . preg_quote($exp) . "(?=\PL|$)/Uiu",
> '%$0%', $texte, $max);
>
> http://fr.php.net/manual/fr/regexp.reference.assertions.php
> http://fr.php.net/manual/fr/regexp.reference.circudollar.php
> http://fr.php.net/manual/fr/regexp.reference.unicode.php
>

Ouah ! Bon, je n'ai pas encore testᅵ mais chapeau !
Je n'avais jamais vu \P.
Tu devrais faire un conf sur unicode ᅵ Paris Web ? :)

Je craignais qu'une limite de mot et ce qui est ou n'est pas un mot
pouvait ᅵtre gᅵnant car je n'ai jamais trouvᅵ (cherchᅵ ?) de dᅵfinitions
exactes de ces classes.

Bon, je ne te remercie pas parce que c'est un peu moi qui t'ai donnᅵ la
solution, que j'ai eu l'extrᅵme gentillesse de partager avec le peuple !
Mais bon, merci qd mᅵme beaucoup ;)

Olivier Miakinen

unread,
Oct 26, 2009, 12:26:05 PM10/26/09
to
Le 26/10/2009 17:08, Olivier Masson a ᅵcrit :
>
>> ... c'est Amen qui a raison,
>
> Ah merde !

Non, Amen. Enfin... tu le prononces comme tu veux.

> Je n'avais jamais vu \P.

Problablement parce que tu ne connaissais pas non plus l'option /u
(PCRE8). Attention, l'un ne va pas sans l'autre !

<cit. http://fr2.php.net/manual/fr/reference.pcre.pattern.modifiers.php>
u (PCRE8)

Cette option dᅵsactive[sic] les fonctionnalitᅵs additionnelles de PCRE
qui ne sont pas compatibles avec Perl. Les chaᅵnes sont traitᅵes comme
des chaᅵnes UTF-8. Cette option est disponible en PHP 4.1.0 et plus
rᅵcent sur plate-forme Unix et en PHP 4.2.3 et plus rᅵcent sur
plate-forme Windows.
</cit.>

En version originale, sans les coquilles de traduction :

<cit. http://fr2.php.net/manual/en/reference.pcre.pattern.modifiers.php>
u (PCRE8)

This modifier turns on additional functionality of PCRE that is
incompatible with Perl. Pattern strings are treated as UTF-8. This
modifier is available from PHP 4.1.0 or greater on Unix and from
PHP 4.2.3 on win32. UTF-8 validity of the pattern is checked since
PHP 4.3.5.
</cit.>

> Bon, je ne te remercie pas parce que c'est un peu moi qui t'ai donnᅵ la
> solution, que j'ai eu l'extrᅵme gentillesse de partager avec le peuple !

:-D

Olivier Masson

unread,
Oct 27, 2009, 6:50:17 AM10/27/09
to
Olivier Miakinen a ᅵcrit :

> En version originale, sans les coquilles de traduction :
>

!!!
C'est prᅵcisᅵment ce que je ne comprenais pas !
Je ne voyais pas trop ᅵ quoi ils faisaient allusion, mais je trouvais ᅵa
dommage de dᅵsactiver des fonctions en passant en utf-8...

Olivier Miakinen

unread,
Oct 27, 2009, 7:34:09 AM10/27/09
to
Le 27/10/2009 11:50, Olivier Masson :

>
>> En version originale, sans les coquilles de traduction :
>
> !!!
> C'est prᅵcisᅵment ce que je ne comprenais pas !

Oui, et je m'ᅵtais fait avoir dans l'une de mes premiᅵres rᅵponses.
Je viens de tenter de joindre le groupe de discussions des traducteurs
de la doc PHP en franᅵais, je verrai bien si je peux contribuer ᅵ
corriger toutes ces coquilles : <http://news.php.net/php.doc.fr/7393>.

0 new messages