preg_replace, limites de mot et caractères accentués

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : preg_replace, limites de mot et caractères accentués

Re: preg_replace, limites de mot et caractères accentués

par Ryle » 04 mai 2015, 12:33

Le plus simple aurait été selon moi de convertir les caractères spéciaux lors de l'enregistrement avec html_entity_decode() et compagnie...
La base serait ainsi homogène, les longueurs de chaîne correspondraient à leur contenu, etc.

Et si pour de nouvelles applications on prévoit l'utf8 dès le départ, tout n'est malheureusement pas encore passés à l'utf8 :(

Mais merci pour ce petit moment nostalgique, laissons maintenant ce sujet retourner se reposer en paix si vous le voulez bien ;)

Re: preg_replace, limites de mot et caractères accentués

par tesmet » 03 mai 2015, 13:34

Bonjour

Tout d'abord, je vois pas trop en quoi les entités HTML cessent d'exister avec UTF-8, é sera correctement affiché dans un document HTML en UTF-8.

Ensuite, le comportement décrit de \b est tout à fait en accord avec les documentations des divers moteurs d'expression régulière implémentant \b et donc de PCRE: (?<=\W)(?=\w)|(?<=\w)(?=\W) et oui, le plus simple est de prendre que la moitié (gauche(?<=\W) ou droite(?=\W)) de la définition car \b& comme ;\b sont tous deux des (*FAIL) obligés.

Personnellement j'aime la négation car les moteurs semblent faire une optimisation sur (*FAIL) et je n'ai pas besoin d'alternatives pour les possibles ^ et $ qui sont tout à fait manquant dans le 3e message que semble avoir adopté Ludo_17. Au cas où ce serait utile à quelqu'un:

Code : Tout sélectionner

echo $texte = '&#233;tabli la cl&#233;.&#233;tabli une cl&#233;'; preg_match_all('/(?<!\w)(?:&#233;tabli|cl&#233;)(?!\w)/', $texte, $resultats); var_dump($resultats);

Re: preg_replace, limites de mot et caractères accentués

par @rthur » 02 mai 2015, 20:22

7 ans après, on est tous en utf8, non ? ;-)

Re: preg_replace, limites de mot et caractères accentués

par davidon96 » 02 mai 2015, 15:57

Bonjour à tous,

Ce qui est dingue, c'est que le problème que soulève Ludo, n'a toujours pas été corrigé dans les différents interprétateur de regex (du moins si on n'est pas en utf8) : 7 ans après.

par Ludo_17 » 04 juin 2008, 14:05

Merci de ta réponse, Caliméro.

J'interviens sur un texte juste avant son affichage. J'ai bien penser remplacer tous les caractères concernés mais cette opération aura alors lieu à chaque consultation du texte. D'ailleurs, s'il y a un avantage à employer des entités de caractères, c'est bien pour les envoyer tel quel au navigateur. Si je les remplace avant...

Comme j'étais assez près du but, j'ai poursuivi mes recherches.
J'ai trouvé une astuce:
J'ai remplacé les limites de mots "\b" encadrant le mot recherché dans la regex par :

(?<=\W) et (?=[^A-Za-z0-9À-ÖØ-öø-ÿ_])

A gauche : reconnait un mot qui suit l'opposé d'un caractère alphanumérique. (c'est curieux, mais ça marche alors que l'équivalent de ce que j'ai placé à droite, non)

A droite : reconnait un mot qui n'est pas suivi des caractères listés.

Avec ça, le texte que j'avais préparé pour mes tests ne comporte plus de manque. Tous les mots sont trouvés, qu'ils commencent par & ou qu'ils finissent par ;

Au niveau du temps d'execution du script, ça à l'air d'aller :wink:
cordialement,
Ludo

par Calimero » 04 juin 2008, 00:59

Bonjour,

Ta question est loin d'être stupide, et la réponse pas forcément simple. J'ai eu une problématique du même genre à gérer (mot[s] variable[s] à surligner dans un contenu HTML variable à l'encodage lui aussi variable, avec une forte contrainte au niveau des performances de la regex).

Si tu le peux, je te conseille d'utiliser des fonctions-filtres (comme html_entity_decode() ) pour nettoyer et homogénéiser le contenu avant de le passer à ta regex (c'est à dire faire disparaître les entités html), ce qui te permettra de contourner le souci.

par Ludo_17 » 03 juin 2008, 22:24

bonsoir,
pas d'idée apparemment ?

Je commence à y voir plus clair dans les références numériques et les références nommées ou entités de caractères à force de chercher des infos. Mais rien sur les limitations éventuelles d'une regex concernant ces références et les limites de mot.

pas évident en tout cas quand on découvre tout ça. Je m'attendais à trouver une réponse ou deux, l'expérience des anciens, des "pros"... mais ma question de débutant est peut-être à placer dans la rubrique "pfff, n'importe quoi..." qui sait... :lol:

Cordialement,
Ludo

preg_replace, limites de mot et caractères accentués

par Ludo_17 » 31 mai 2008, 22:13

bonjour à tous,

comment indiquer une limite de mot dans une regex, quand le mot commence ou fini par &.#...; donc une entité numérique de caractère accentué (ISO-8859-1)

(Je place un point entre & et # dans le code ci-dessous car j'ignore s'il sera interprété)

Dans un script php, j'ai besoin de remplacer un mot issu d'une variable contenant un texte html. Ce mot peut bien sûr comporter des accents et les caractères accentués se présentent sous au moins deux formes possibles en raison des différents éditeurs utilisés pour la rédaction du texte : exemple é et &.#233; (voire même &.eacute;)

Aucun soucis avec les caractères accentués normaux (é)

par contre, les entités &.#233; (ou &eacute;) empêchent l'interpretation de la limite de mot lorsqu'ils sont placés au début ou à la fin du mot. Du coup, tout se passe comme si les \b de la regex n'étaient pas présents.

si j'utilise un logiciel testeur de regex (exemple regex coach), je constate aussi le problème.

Exemple, cas du mot commençant par un caractère accentué :
dans le texte, je place : établi, rétabli, &.#233;tabli, r&.#233;tabli
en testant la regex : \b(établi|&.#233;tabli)\b

les caractères accentués "normaux" ne posent pas de problème : établi est trouvé, rétabli ne l'est pas.

Mais &.#233;tabli n'est pas trouvé alors que r&.#233;tabli, oui, comme si il n'y avait pas de limite de mot \b.

Même constat avec un caractère accentué à la fin : clé, clés et cl&.#233;, cl&.#233;s
la regex : \b(clé|cl&.#233;)\b

clé est trouvé et pas clés donc c'est parfait.
Mais cl&.#233; n'est pas trouvé (il le devrait pourtant) et cl&.#233;s est trouvé montrant que la limite de mot avant ne fonctionne pas.

Bien sûr, si je fais \bcl&.#233;\b, le problème est le même.

j'ai beau chercher parmis les nombreuses docs volumineuses que l'on peut trouver sur le net (preg_replace, PCRE, caractères ISO...), je ne vois pas de solution.

merci de vos réponses,
cordialement,
Ludo :wink: