PapyJP a écrit :
Bonsoir à tous
Je cherche à découper une chaîne de caractères en "fractions".
Le texte d'entrée est
Ceci est une @#tuilette1, suivie d'une @#tuilette2 et d'autres babioles.
Je voudrais obtenir un tableau contenant:
["Ceci est une ", "@#tuilette1", ", suivie d'une ", "@#tuilette2", " et d'autres babioles."]
Je n'arrive pas à faire la rexexp qui me donne ce résultat.
Mon dernier essai (toujours infructueux):
var valueParts = itemValue.match(/(^.*?)(@#[A-za-z0-9_-]*|$)/g);
Merci de votre aide
Suis pas spécialiste de PHP, aussi me suis-je dis que cela pourrait être intéressant à titre d'exercice commenté
.
A priori, je ne recours pas aux expressions régulières, et préfère procéder comme je le fais en Java, c'est à dire à la mano et de façon rustique. C'est brut, pas beau, mais portable et on ne se casse pas la tête avec les spécificités des expressions régulières. Une seule expression est utilisée, pour identifier les mots clés. Le reste, c'est du découpage de texte en petits bouts transférés dans un tableau.
Le code PHP ci-après n'est par conséquent ni génial, ni optimisé, et peut-être ne fonctionne-t-il pas dans tous les cas. Je le mets toutefois ici pour voir s'il tient la route et soulève, sinon l'enthousiasme, du moins les critiques (forcément constructives, hein...).
<?php
function split($input,$pattern)
{
// Initialisation du tableau récupéré en sortie
$output = [];
// Tant que le tampon n'est pas null ou vide
while (is_null($input) ? false : strlen($input) > 0)
{
// Recherche du prochain mot clé
preg_match(PATTERN,$input, $matches, PREG_OFFSET_CAPTURE);
// Test dimension tableau contenant le résultat de la recherche
// [0] -> Mot clé récupéré
// [1] -> Position du mot clé dans le tampon dans un domaine 0..N-1
$size = is_null($matches) ? 0 : count($matches);
// Traitement différencié selon résultat recherche mot clé
switch ($size)
{
case 0 :
{
// Le tampon ne contient aucun mot clé
// -> ajout du tampon dans le tableau en sortie
// -> réinitialisation du tampon en tant que chaîne vide (fin de traitement)
array_push($output,$input);
$input = '';
break;
}
case 1 :
{
// Le tampon contient au moins un mot clé
// -> récupération du mot clé trouvé
// -> récupération de la position du mot clé dans le tampon
// -> récupération de la partie éventuellement située avant le mot clé dans le tampon
$token = $matches[0][0];
$offset = $matches[0][1];
// Un peu de parano...
if ($offset < 0) throw new Exception("Unexpected offset value");
$part = $offset > 0 ? substr($input,0,$offset) : '';
// Ajout dans le tableau en sortie de la partie avant mot clé si non nulle ou vide
if ((is_null($part) ? 0 : strlen($part)) > 0)
{
array_push($output,$part);
}
array_push($output,$token);
// Suppression de la partie avant (si existe) + mot clé dans le tampon
$input = substr($input,$offset + strlen($token));
break;
}
default :
{
// Erreur
throw new Exception('Too many tokens found.');
}
}
}
return $output;
}
// Expression régulière à utiliser pour extraire les mots clés
const PATTERN = '/@#tuilette\d{1,5}/';
// Initialisation de la chaîne alphanumérique en entrée
$text = 'Ceci est une @#tuilette1, suivie d\'une @#tuilette2 et d\'autres babioles.';
$parts = split($text,PATTERN);
print_r($parts);
?>
J'ai posé comme postulat qu'il n'y aurait pas plus de 5 chiffres en fin de mot clé, mais l'expression peut bien entendu être adaptée si cette valeur s'avère être supérieure.
Ci-dessous le résultat obtenu sur un éditeur PHP en ligne :
Array ( [0] => Ceci est une [1] => @#tuilette1 [2] => , suivie d'une [3] => @#tuilette2 [4] => et d'autres babioles. )
Voilà, voilà...
Pas le temps de tester tous les cas de figure, mais si certains veulent s'amuser avec et constatent des erreurs, les retours seront appréciés.
Merci d'avance.
Modifié par sepecat (30 Mar 2017 - 22:53)