J'ai un fichier .php qui est en fait un fichier SVG avec du code PHP en ligne. Appelons-le inner.php:

<?php 
    $uuid = uniqid();
?>
<svg class="__combo" id=<?php echo $uuid ?>
...
</svg>

J'écris un autre fichier php qui devrait émettre le contenu de inner.php mais avec toutes les instances de <?php ... ?> remplacées par une chaîne (par exemple "AA"). Le fichier (appelons-le external.php) ressemble à ceci maintenant :

    <?php 
        $svg_body = file_get_contents("inner.php"));
        $replaced = preg_replace("??","AA" , $svg_body);

        echo "$replaced"
    ?>

J'ai marqué avec "??" la partie où je voudrais mettre une expression régulière pour contenir n'importe quelle chaîne commençant par "<?php" et se terminant par la première occurrence de "?>". Et le résultat que je m'attends à voir est

    "AA"
    <svg class="__combo" id="AA"
    ...
    </svg>

Fondamentalement, je ne trouve pas de moyen d'échapper à la chaîne contenant les <?php et ?> en PHP

0
Louis Shraga 21 nov. 2018 à 01:05

3 réponses

Meilleure réponse

Cette expression semble bien fonctionner ...

preg_replace('/<\?(php\s|=).*\?>/siU', '"AA"', $svg_body);

Démo ~ https://3v4l.org/0Ci9d

Pour le décomposer ...

  • <\?(php\s|=) - une correspondance littérale pour "<?php" (point d'interrogation échappé) suivi d'un espace blanc (peut être une nouvelle ligne) ou l'écho court <?=
  • .* - zéro caractère ou plus
  • \?> - une correspondance littérale pour "?>"
  • s - définit * pour qu'il corresponde aux nouvelles lignes, requis pour votre premier bloc <?php ... ?>
  • i - insensible à la casse car pourquoi pas
  • U - sans gêne. Signifie que * correspond aux arrêts au premier motif suivant, pas au dernier. Ceci pour empêcher * de faire correspondre tout entre le premier "<?php" et le dernier "?>"

Voir ici pour plus d'informations sur les modificateurs ~ http://php.net/manual /reference.pcre.pattern.modifiers.php

2
Phil 20 nov. 2018 à 22:37

Essayez d'abord de faire cela sans RegEx. Vous pouvez essayer avec substr_replace.

$replaced = substr_replace($svg_body, 'AA', strpos($svg_body, '<?php'), strpos($svg_body, '?>'));

Si vous avez vraiment besoin de RegEx, essayez quelque chose comme ceci:

$replaced = preg_replace(/(<\?php[\s\S]+?\?>)/, "AA", $svg_body);
0
Nick 20 nov. 2018 à 22:26

Une alternative consiste à utiliser l'analyseur de PHP via l'extension tokenizer:

<?php

$tokens = token_get_all("<svg>\n<?php echo; ?></svg>");

$result='';
$in_php = false;
foreach ($tokens as $token) {
   if ($token[0]==T_INLINE_HTML) {
     $result .= $token[1];
     $in_php = false;
   } else if (!$in_php) {
     $result .= "AAA";
     $in_php=true;
    }
}

echo $result;

https://3v4l.org/jEpYi

Cela présente l'avantage de gérer également d'autres balises ouvertes, comme <?= et les fichiers sans balise de fermeture. Et gère les cas où la balise de fermeture apparaît également dans le code PHP (c'est-à-dire dans un commentaire)

2
johannes 20 nov. 2018 à 22:42