Page 1 sur 1
Expressions régulières : mettre les mots en majuscule dans un texte, en gras
Posté : 07 nov. 2017, 02:48
par Dharius
Bonjour,
J'ai des textes pour lesquels j'aimerai mettre automatiquement les mots qui sont en majuscule, en gras.
Par exemple si on trouve le mot "BONJOUR", cela sera transformé en "<strong>BONJOUR</strong>".
Cependant je n'arrive pas à créer d'expression régulière en PHP pour faire ça... J'ai besoin de vous ! Merci.
Voici un exemple de texte pour s'entraîner :
---
M. Cui s'exprimait lors d'un point de presse organisé à l'ambassade chinoise à Washington.
UNE OPPORTUNITÉ HISTORIQUE
M. Trump devrait se rendre en Chine le mois prochain dans le cadre de sa tournée en Asie, qui l'amènera également au Japon, en Corée du Sud, au Vietnam et aux Philippines.
"UNE VISITE D'ÉTAT PLUS"
M. Cui a indiqué que la Chine serait ravie de fournir une expérience de "visite d'Etat plus" au président Trump et à sa famille.
---
Un grand MERCI pour votre aide !!!
Re: Expressions régulières : mettre les mots en majuscule dans un texte, en gras
Posté : 07 nov. 2017, 18:10
par tesmet
Code : Tout sélectionner
$texte = <<<__texte__
M. Cui s'exprimait lors d'un point de presse organisé à l'ambassade chinoise à Washington.
UNE OPPORTUNITÉ HISTORIQUE
M. Trump devrait se rendre en Chine le mois prochain dans le cadre de sa tournée en Asie, qui l'amènera également au Japon, en Corée du Sud, au Vietnam et aux Philippines.
"UNE VISITE D'ÉTAT PLUS"
M. Cui a indiqué que la Chine serait ravie de fournir une expérience de "visite d'Etat plus" au président Trump et à sa famille.
__texte__;
// \p indique qu'on utilisera une propriété
// {Lu} indique qu'on s'intéresse aux lettres (letter) majuscules (uppercase)
// + pour prendre toute séquence d'au moins 1 lettre majuscule ou plus...
// \b est une assertion pour détecter la frontière de mot, donc tout le mot doit-être en majuscule
// car la séquence de lettres majuscule doit-être encadrée par des frontières de mot
$regex = '#\b\p{Lu}+\b#u'; // enlever le u après le # si la chaine n'est pas en UTF-8
echo preg_replace($regex, '<strong>$0</strong>', $texte); // $0 réfère à la capture globale
// remplacer le + par {2,} indiquerait que la séquence devrait avoir au moins 2 lettres majuscule
// donc le M dans M. trump ne sera pas en gras car il faut un mot en majuscule s'au moins 2 lettres ou plus
// enlever le u après le # si la chaine n'est pas en UTF-8
echo preg_replace('#\b\p{Lu}{2,}\b#u', '<strong>$0</strong>', $texte);
Re: Expressions régulières : mettre les mots en majuscule dans un texte, en gras
Posté : 08 nov. 2017, 03:46
par Dharius
Bonjour,
Ouah ! Merci pour cette réponse détaillée ! C'est très pédagogique et instructif !
Par contre j'ai un problème avec cette solution : s'il y a un apostrophe, cela ne marchera pas correctement car l'apostrophe n'est pas considéré comme une lettre. comment faire pour ajouter le ' par exemple (ex: TEST AVEC L'APOSTROPHE) et éventuellement d'autres caractères ?
MERCIIII !
Re: Expressions régulières : mettre les mots en majuscule dans un texte, en gras
Posté : 08 nov. 2017, 10:33
par tesmet
Bonjour,
On peut faire sa propre classe de caractères avec les crochets [] donc [\p{Lu}\'] voudrait dire d'inclure les lettres majuscules et l'apostrophe que j'ai échappé pour éviter un possible conflit avec PHP. Par contre, en encadrant avec des \b on pourrait détecter une frontière de mot avec une lettre minuscule car la classe de caractère inclue autre chose que des majuscules.
Code : Tout sélectionner
echo htmlspecialchars(preg_replace('#\b[\p{Lu}\']{2,}\b#u', '<strong>$0</strong>', "D'ÉTAT s'MAIS's"));
// affichera <strong>D'ÉTAT</strong> s<strong>'MAIS'</strong>s
// car les frontières seraient détectées entre les s minuscules et les apostrophes
Si ce n'est pas bon j'irais probablement vers un groupe facultatif avec * après le premier \b
Code : Tout sélectionner
$regex = '#\b(\p{Lu}+[\' ])*\p{Lu}{2,}\b#u'; // j'ai ajouté un espace dans la classe de caractères
echo htmlspecialchars(preg_replace($regex, '<strong>$0</strong>', "D'ÉTAT s'MAIS's MOTS ENSEMBLES car AJOUT De l'ESPACE"));
// affichera <strong>D'ÉTAT</strong> s'<strong>MAIS</strong>'s <strong>MOTS ENSEMBLES</strong> car <strong>AJOUT</strong> De l'<strong>ESPACE</strong>
Mais pour être exact il est peut-être préférable de construire ses propres frontières. Pour le \b de gauche (?<!\pL) pour dire n'est pas précédé d'une lettre et (?=\p{Lu}) pour dire doit-être suivi d'une lettre majuscule. Le \b de droite sera l'inverse (?<=\p{Lu}) doit-être précédé d'une lettre majuscule et (?!\pL) n'est pas suivi d'une lettre majuscule
Code : Tout sélectionner
$regex = '#(?<!\pL)(?=\p{Lu})[\p{Lu}\' ]{2,}(?<=\p{Lu})(?!\pL)#u'; // j'ai ajouté un espace dans la classe de caractères
echo htmlspecialchars(preg_replace($regex, '<strong>$0</strong>', "D'ÉTAT s'MAIS's MOTS ENSEMBLES car AJOUT De l'ESPACE"));
// affichera <strong>D'ÉTAT</strong> s'<strong>MAIS</strong>'s <strong>MOTS ENSEMBLES</strong> car <strong>AJOUT</strong> De l'<strong>ESPACE</strong>