Je suis actuellement en train de créer un moteur d'analyse de bbcode et j'ai rencontré une situation que je ne peux pas résoudre seul.
Le problème est que je me suis retrouvé face à un problème exactement similaire à celui-ci : Apache / PHP on Windows crashes with regular expression
Cela signifie que si je fais quelque chose comme l'exemple ci-dessous, Apache plante à cause du compteur de récursion qui atteint 690 (limite de mémoire de 1 Mo pour PCRE) :
$txt = '[b]'.str_repeat('a', 338).'[/b]'; // si je réduis la valeur de la répétition, ça fonctionne
$regex = '#\[(?P(?P[a-z0-9_]*?)(?:=.*?|\s.*?|))](?P(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)\[/(?P=tag)]#mi';
echo preg_replace_callback($regex, function($matches) { return $matches['content']; }, $txt);
Je dois donc somehow minimiser le besoin de *
et de +
dans mon regex, mais c'est là que je suis à court d'idées, donc je pensais que vous pourriez suggérer quelque chose.
D'autres approches pour l'analyse du bbcode (qui pourraient gérer les balises imbriquées) sont les bienvenues. Cependant, je n'aimerais pas utiliser une classe déjà existante ou autre. J'aime faire les choses par moi-même !
J'ai également jeté un œil à PECL et Pear HTML_BBCodeParser. Mais je ne veux pas que mon application dépende d'extensions. Il est plus probable que je fasse un script qui vérifie si cette extension existe et si ce n'est pas le cas, utilise l'analyseur BBCode que j'essaie de faire ici.
Désolé si mes descriptions sont sombres, je ne suis pas un pro en anglais ^^
EDIT. Ainsi, le regex expliqué :
\[(?P(?P[a-z0-9_]*?)(?:=.*?|\s.*?|))]
Ceci est ma balise d'ouverture. J'ai utilisé des groupes nommés. Avec 'tag', j'identifie la balise et avec 'attributes', j'identifie les attributs de balises. Pensez à la balise comme un attribut aussi. Que se passe-t-il ici ? J'essaie de faire correspondre une balise, lorsque la balise est trouvée, j'essaie de faire correspondre tout ce qui se trouve après le signe de =
ou après \s
(espaceur) jusqu'à ce qu'il atteigne la fermeture de la balise ]
.
(?P(?:[^[]|\[(?!/?(?P=tag)])|(?R))+?)
Maintenant, ici j'essaie de faire correspondre le contenu. C'est la partie délicate. Je recherche un caractère qui n'est pas [ et si j'en trouve un, alors je vérifie s'il ne s'agit pas de ma balise de fin ou de récursion, et je dis au moteur de regex de le faire jusqu'à ce que....
\[/(?P=tag)]
... la balise de fin soit trouvée.