GNT sans publicité, site mobile, fonctionnalitées exclusives...

Expression reguliere pour corriger la=?windows-1252?Q?_typographie_d'un_texte?

Le
Sebastien
Bonjour à tous,

Je cherche à corriger automatiquement la typographie d'un texte, saisi
par l'utilisateur dans un textarea HTML.
Cette correction est facultative, une case à cocher permet de l'activer
ou non et de plus il y a une prévisualisation avant soumission
définitive. Voici pour le décor.

-> essais de regexp en fin de post.

Objectifs :

Il s'agit de corrections pour les erreurs les plus fréquentes, comme
l'oubli de l'espace (insécable) avant les ponctuations doubles : ; ! ?
et à l'intérieur des guillemets français « et ».

Si l'espace est absent on ajoute un espace insécable, si un espace
normal est présent on le transforme en espace insécable.

Raffinement ultime (et complications à l'horizon), auquel je tiens
beaucoup, l'apostrophe droite est transformée en apostrophe «
typographiquement correcte » (').

Complication supplémentaire (voir point précédent), le texte peut
contenir du pseudo-code Wiki, avec en particulier '' (deux apostrophes
droites) entourant du texte devant être rendu en italique.

Pour finir, le tout est à destination d'une base de données MySQL, mais
cela n'a aucune incidence (si je ne m'abuse) car la chaîne sera insérée
avec mysql_real_escape_string(). On considère que la chaîne (reçue en
POST) est passée par stripslashes() si nécessaire avant tout traitement.


Les expressions :

<?php
function cleanup_typo($str)
{
$patterns[0] = '/([^\'].)\'([^\'].|0)/'; // Apostrophe droite non
précédée d'une autre apostrophe
$patterns[1] = '/([^ ]):/'; // Deux-points non précédé d'un espace
$patterns[2] = '/([^ ]);/'; // Point-virgule non précédé d'un espace
$patterns[3] = '/«([^ ])/'; // Guillemet ouvrant non suivi d'un espace
$patterns[4] = '/([^ ])»/'; // Guillemet fermant non précédé d'un espace
$patterns[5] = '/([^ ])!/'; // Point d'exclamation non précédé d'un espace
$patterns[6] = '/([^ ])\?/'; // Point d'interrogation non précédé d'un
espace
$patterns[7] = '/\.{3}/'; // Trois-points

$replacements[0] = '$1'$2';
$replacements[1] = '$1 :';
$replacements[2] = '$1 ;';
$replacements[3] = '« $1';
$replacements[4] = '$1 »';
$replacements[5] = '$1 !';
$replacements[6] = '$1 ?';
$replacements[7] = '--';

$str = preg_replace($patterns, $replacements, $str);

/* Ces 2 lignes sont issues de wiki2html : conversion en espaces
insécable des espaces existants */
$str = preg_replace('/[ ]+([:?!;»])/',' $1',$str);
$str = preg_replace('/(«)[ ]+/','$1 ',$str);

return $str;
}
?>

Si vous avez lu jusqu'ici sans tricher, bravo et merci.

Je suis intéressé par vos observations à tous les niveaux :
- problèmes liés aux risques de remplacer du texte qui ne devrait pas l'être
- erreurs dans les regexp (pourtant testée, mais peut-être pas sur tous
les cas)
- Possibilités d'optimisation
- Mauvaise interprêtation des règles de typographie française
-

Ceci n'est qu'un premier jet, je ne suis toujours pas un expert en
expressions régulières. Je n'ai fait que quelques tests e tje sens que
mes expressions sont pleines de trous


Sébastien
Lire les 10 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Sebastien
Le #119076
Bonjour à tous,

Je ne sais pas si mon idée vous paraît trop farfelue ou quoi, laissez
quand même vos impressions.

Quelques modifications :

Pour ne pas transformer "http:" en "http :"
j'ai ajouté ces lignes en fin de fonction :

<?php
$str = preg_replace('/(http|https|ftp|news|mailto) :/','$1:',$str);
$str = preg_replace('/(http|https|ftp|news|mailto) :/','$1:',$str);
?>

De plus j'ai oublié de préciser que dans les remplacements les espaces
insérés ou remplacés sont des espaces insécables directement saisis sous
forme de caractère, pour éviter que les esperluettes des appels &#160;,
&#xa0; ou &nbsp; ne soient à leur tour convertis en &amp; (donnant
respectivement &amp;#160;, &amp;#xa0; et &amp;nbsp;) par
htmlspecialchars() ou htmlentities().

Sébastien
Florian Sinatra
Le #118936
*Sebastien* @ 26/03/2006 11:54 :

Note préliminaire : je suis une bille en ExpReg.

<?php
function cleanup_typo($str)
{
$patterns[0] = '/([^'].)'([^'].|0)/'; // Apostrophe droite non
précédée d'une autre apostrophe
$patterns[1] = '/([^ ]):/'; // Deux-points non précédé d'un espace
$patterns[2] = '/([^ ]);/'; // Point-virgule non précédé d'un espace
$patterns[3] = '/«([^ ])/'; // Guillemet ouvrant non suivi d'un espace
$patterns[4] = '/([^ ])»/'; // Guillemet fermant non précédé d'un espace
$patterns[5] = '/([^ ])!/'; // Point d'exclamation non précédé d'un espace
$patterns[6] = '/([^ ])?/'; // Point d'interrogation non précédé d'un
espace
$patterns[7] = '/.{3}/'; // Trois-points


A l'avenir, tu pourrais utiliser un autre délimiteur :

$replacements[0] = '$1'$2';


Ca n'a aucune chance de fonctionner : tu dois avoir une erreur de
parsing. Echappe ton apostrophe entre $1 et $2.

$replacements[1] = '$1 :';
$replacements[2] = '$1 ;';
$replacements[3] = '« $1';
$replacements[4] = '$1 »';
$replacements[5] = '$1 !';
$replacements[6] = '$1 ?';
$replacements[7] = '--';


Pourquoi remplacer les trois points par deux tirets ?

$str = preg_replace($patterns, $replacements, $str);

/* Ces 2 lignes sont issues de wiki2html : conversion en espaces
insécable des espaces existants */
$str = preg_replace('/[ ]+([:?!;»])/',' $1',$str);
$str = preg_replace('/(«)[ ]+/','$1 ',$str);


Ces espaces n'ont rien d'insécable. Et tu ne pourras les insécabiliser
après, vu qu'il sera impossible de les différencier...

Olivier Miakinen
Le #118935


$replacements[0] = '$1'$2';


Ca n'a aucune chance de fonctionner : tu dois avoir une erreur de
parsing. Echappe ton apostrophe entre $1 et $2.


Je suppose que c'est le gentil robot de modération qui a transformé son
apostrophe CP1252 en patte de mouche ASCII. ;-)

Cela dit, Sébastien, je te déconseille d'utiliser CP1252 pour ta page
web -- et ce d'autant plus si tu déclares ISO-8859-1.

Il vaudrait mieux écrire :
$replacements[0] = '$1&rsquo;$2';
ou bien :
$replacements[0] = '$1&#8217;$2';

À moins que ta page ne soit en UTF-8, auquel cas il n'y a pas de problème.

$replacements[7] = '--';


Pourquoi remplacer les trois points par deux tirets ?


Pas compris non plus. C'est encore le robot qui a corrigé le code
CP1252 ?

Tu peux écrire :
$replacements[7] = '&hellip;';

Mais personnellement j'ai horreur de ce caractère « trois points » et je
préfère garder « ... ».

/* Ces 2 lignes sont issues de wiki2html : conversion en espaces
insécable des espaces existants */
$str = preg_replace('/[ ]+([:?!;»])/',' $1',$str);
$str = preg_replace('/(«)[ ]+/','$1 ',$str);


Ces espaces n'ont rien d'insécable. Et tu ne pourras les insécabiliser
après, vu qu'il sera impossible de les différencier...


Alors là ce n'est pas à cause du robot, mais de vos nouvelleurs à
tous les deux. Sébastien utilise Thunderbird qui remplace les espaces
insécables par des espaces simples à l'envoi, et toi tu utilise aussi
Thunderbird qui les aurait remplacées aussi à la lecture si ce n'avait
pas été fait à l'envoi. Et avec mon Mozilla je ne peux pas non plus
distinguer les deux.

--
Olivier Miakinen
Troll du plus sage chez les conviviaux : le nouveau venu, avec
son clan, s'infiltre dans les groupes de nouvelles. (3 c.)


Florian Sinatra
Le #118933
*Olivier Miakinen* @ 28/03/2006 19:03 :


$replacements[0] = '$1'$2';


Ca n'a aucune chance de fonctionner : tu dois avoir une erreur de
parsing. Echappe ton apostrophe entre $1 et $2.



Je suppose que c'est le gentil robot de modération qui a transformé son
apostrophe CP1252 en patte de mouche ASCII. ;-)


Cette fameuse apostrophe, elle est censée ressembler à quoi ? C'est que
dans CP1252 ? Elle s'obtient par le clavier ?

Alors là ce n'est pas à cause du robot, mais de vos nouvelleurs à
tous les deux. Sébastien utilise Thunderbird qui remplace les espaces
insécables par des espaces simples à l'envoi, et toi tu utilise aussi
Thunderbird qui les aurait remplacées aussi à la lecture si ce n'avait
pas été fait à l'envoi. Et avec mon Mozilla je ne peux pas non plus
distinguer les deux.


Idem, comment l'obtenir ? Quel est son code ?



Sebastien
Le #118934

Merci Olivier d'avoir répondu, fort justement, à ma place. Je vais donc
confirmer et préciser également pour Florian. Merci pour vos réponses.

$replacements[0] = '$1'$2';


Ca n'a aucune chance de fonctionner : tu dois avoir une erreur de
parsing. Echappe ton apostrophe entre $1 et $2.


Je suppose que c'est le gentil robot de modération qui a transformé son
apostrophe CP1252 en patte de mouche ASCII. ;-)


Tout à fait. J'ai fait l'erreur de ne pes prévor des explications à ce
sujet.

Cela dit, Sébastien, je te déconseille d'utiliser CP1252 pour ta page
web -- et ce d'autant plus si tu déclares ISO-8859-1.


Jamais je n'utiliserais CP1252 sur le web, sois-en assuré !

À moins que ta page ne soit en UTF-8, auquel cas il n'y a pas de problème.


C'est effectivement le cas et je précise donc que tout est sensé être en
utf-8, même les données à corriger.

$replacements[7] = '--';


Pourquoi remplacer les trois points par deux tirets ?


Pas compris non plus. C'est encore le robot qui a corrigé le code
CP1252 ?


Encore exact,

Mais personnellement j'ai horreur de ce caractère « trois points » et je
préfère garder « ... ».


Je préfère pour ma part le trois-points sous forme de caractère.
Question de goût, mais c'est facilement adaptable par chacun.

/* Ces 2 lignes sont issues de wiki2html : conversion en espaces
insécable des espaces existants */
$str = preg_replace('/[ ]+([:?!;»])/',' $1',$str);
$str = preg_replace('/(«)[ ]+/','$1 ',$str);


Ces espaces n'ont rien d'insécable. Et tu ne pourras les insécabiliser
après, vu qu'il sera impossible de les différencier...


Alors là ce n'est pas à cause du robot, mais de vos nouvelleurs à
tous les deux. Sébastien utilise Thunderbird qui remplace les espaces
insécables par des espaces simples à l'envoi, et toi tu utilise aussi
Thunderbird qui les aurait remplacées aussi à la lecture si ce n'avait
pas été fait à l'envoi. Et avec mon Mozilla je ne peux pas non plus
distinguer les deux.


Je pense que ça vient de plus loin : Windows transforme apparemment les
espaces insécables en espaces normaux au moment de la copie (Ctrl+V).
Car il s'agit bien dans mon code d'un espace insécable sous forme de
caractère, que'on ne peut donc pas distinguer même en tant que tel. La
raison est celle que j'ai déjà donnée : le risque de voir les
esperluettes d'un appel de caractère transformée en &amp;.

Sur ce point si vous avez des idées...

Sébastien



Publicité
Suivre les réponses
Poster une réponse
Anonyme