Forum > Autres langages > Expressions régulières : \b et les accents

Expressions régulières : \b et les accents

avatar de Tony_
Administrateur
# Le 16/04/2010 à 16h00
Bonjour.
Les expressions régulières sont très pratiques pour attraper facilement un mot. L'utilisation de "\b" représente un word boundaries (limite de mot). Cela fonctionne très bien sur mon ordinateur en local, mais mon espace d'hébergement web ne considère pas les caractères accentués comme des caractères alphanumérique. De ce fait, j'ai un code PHP qui n'attrape pas les mots qui commence ou se termine par un caractère accentué. Cela est dommage, d'autant plus que le code fonctionne parfaitement en locale sur mon ordinateur.

Voici un exemple du code PHP dont il est question:
Code:
$msg = 'du pli, il doit être écourté. Selon Steve Krug (expert en usabilité) il ... Un site qui est indexé sur';
$regex = '#\b(usabilité|Steve)\b#iU';
$substitute = '<span style="text-decoration:underline; color:red;">$0</span>';

$msg2 = preg_replace($regex, $substitute, $msg);

echo '<p>'.$msg.'</p>';
echo '<p>'.$msg2.'</p>';


J'ai trouvé une documentation sur Python qui indique que sur les machines française, les caractères accentués sont considéré comme des caractères alphanumérique alors que ce n'est pas le cas sur les machines anglaises. Voir cette documentation au chapitre "3.5 Compilation Flags" et au paragraphe "LOCALE".

Mon problème consiste donc à savoir comment modifier "\b" pour qu'il accepte les caractères accentués. Faut-il que je modifie mon code PHP ou que je modifie un code Python (ou autre)? Par ailleurs, je tiens à préciser que mon espace d'hébergement ne me donne pas accès à Python (sauf si je paye un supplément).

Merci par avance pour vos réponses.
Bien cordialement.
N'hésitez pas à consulter le dossier référencement. smiley
Sinon hors internet je suis développeur web PHP.
avatar de stc
Membre
# Le 18/04/2010 à 03h13
Je ne comprend pas pourquoi tu veux mettre \b ,ça marche bien sans ,pusi si tu veux pas de chevauchement met l'option adéquat (je sais plus c'est laquelle mais elle existe c'est sur)
avatar de Tony_
Administrateur
# Le 18/04/2010 à 13h11
Non, je suis obligé de mettre \b sinon voici un exemple où ça peut poser problème:
Code:
$msg = 'Lorem ipsum dolor sit commentaire amet.';
$regex = '#aire#iU';
$substitute = '<span style="text-decoration:underline; color:red;">$0</span>';

$msg2 = preg_replace($regex, $substitute, $msg);

echo '<p>'.$msg.'</p>';
echo '<p>'.$msg2.'</p>';

Dans le code suivant, si je retire \b l'expression régulière attrapera la partie du mot "commentaire". Or, je souhaite que ça prenne uniquement les mots entiers.
J'ai cherché sur internet et je ne suis pas le seul à avoir ce problème. Le soucis, c'est que personne n'a pu donner une réponse adéquat sur tous les sujets que j'ai pu voir.

Je pense que le problème est plus compliqué que tu ne le pense. Toutefois, si tu trouve la solution, je te félicite. smiley

Cordialement.
N'hésitez pas à consulter le dossier référencement. smiley
Sinon hors internet je suis développeur web PHP.
avatar de stc
Membre
# Le 18/04/2010 à 17h35
une idée comme ça mais si tu met un un espace dans le motif avant 'aire' ça ne prend plus celui de commentaire ?
avatar de Tony_
Administrateur
# Le 18/04/2010 à 19h36
En théorie pour implémenter cette idée il faut mettre un espace avant et après le mot. Car le même problème est rencontré si j'ai par exemple "bon" et "bonjour". Malheureusement, les séparateurs de mots peuvent être des espaces mais également des caractères tel que: .,;:/().
Par ailleurs, si le mot est placé en début de chaine, il n'y aura pas d'espace donc le mot ne sera jamais capturé par l'expression régulière.

D'après ce que j'ai compris, l'avantage de \b c'est qu'il détecte chaque fois qu'un élément alphanumérique est suivis d'un élément non-alphanumérique et inversement. En d'autres termes, il ne détecte pas des caractères particuliers mais un "changement" dans une suite de caractère.

Explication de \b


Pour illustrer mes propos, considérons une chaine de caractère suivante:
"bonjour à tous, j'adore l'usabilité et le célèbre Steve Krug."
Pour bien comprendre "\b" je recommande de remplacer tous les caractères alphanumérique par des 1 et tous les caractères non-alphanumérique par des 0. La chaine devient alors:
"111111101011110010111101011111111101101101111111011111011110"
La force de \b c'est qu'il détecte les changements d'état. Il détecte les passages de 0 à 1 et les passages allant de 1 à 0. Par contre, lorsqu'il y a une succession de 1 ou une succession de 0, "\b" n'intervient pas.

Mon problème c'est que mon serveur détecte les caractères spéciaux comme des caractères non-alphanumérique (au même titre que point, virgule, parenthèse ...). La chaine ci-dessus devient alors:
"1111111000111100101111101011111111001101101010111011111011110"
Pour résumer voici les chaines mises en valeurs pour bien cerner les différences:
1) "bonjour à tous, j'adore l'usabilité et le célèbre Steve Krug."
2) "1111111010111100101111101011111111101101101111111011111011110"
3) "1111111000111100101111101011111111001101101010111011111011110"
La chaine (2) c'est ce que j'ai sur ma machine en locale et la chaine (3) c'est mon serveur web.
N'hésitez pas à consulter le dossier référencement. smiley
Sinon hors internet je suis développeur web PHP.
avatar de stc
Membre
# Le 18/04/2010 à 20h04
J'ai trouvé une bidouille ,c'est pas terrible mais bon ça fonctionne:
Code:
<?php
header('Content-Type: text/html; charset=utf-8');
$msg = 'du pli, il doit être écourté. Selon Steve Krug (expert en usabilité) il ... Un site qui est indexé sur';
$regex = '#\b(usabilité|Steve)\b#iU';
$msg=str_replace('é', 'eaiou', $msg);
$regex=str_replace('é', 'eaiou', $regex);

$substitute = '<span style="text-decoration:underline; color:red;">$0</span>';

$msg2 = preg_replace($regex, $substitute, $msg);

$msg2=str_replace('eaiou', 'é', $msg2);
echo '<p>'.$msg.'</p>';
echo '<p>'.$msg2.'</p>';
?>

J'ajoute que str_replace est une fonction assez rapide d'après ce que j'ai pu en lire.
+++
avatar de Tony_
Administrateur
# Le 18/04/2010 à 23h59
Bien vue pour cette idée ingénieuse. Je m'étais toujours concentré sur l'expression régulière, sans jamais pensé à des solutions alternatives. Par contre je conçois que c'est une solution de pas très propre.
D'après le petit test que j'ai effectué en grandeur nature ça m'enlève quelques bugs mais je n'arrive toujours pas à attraper les mots. Il va falloir que je fasse quelques tests, mais je pense que c'est une bonne piste à explorer.
Merci pour ce coup de main. smiley
N'hésitez pas à consulter le dossier référencement. smiley
Sinon hors internet je suis développeur web PHP.