6
votes

PHP Preg_quote dans la chaîne de remplacement

J'utilise Preg_replace et je veux inclure une URL à l'intérieur de la chaîne de remplacement. Comment citer cette chaîne? Il semble que Preg_quote est uniquement pour le modèle de recherche.

$replace = '\1'.addslashes($url).'\3'.addslashes($title).'\4';


4 commentaires

Qu'essayez-vous de faire? La chaîne de remplacement n'est pas transmise via le moteur Regex et ne doit donc pas être échappée. Toutes les références de retour doivent être référencées par 1 $ , 2 $ , etc.


Vous pouvez ajouter davantage d'un exemple à votre question, il est donc clair que vous faites.


@hakre, évidemment OP veut savoir comment échapper correctement aux chaînes de remplacement dans Preg_replace afin que le remplacement soit exactement ce qui est à l'origine dans la chaîne (peu importe son contenu). Que voudriez-vous savoir de plus?


@Qtax: Quel est le sujet $ ? Qu'est-ce que $ URL ? Qu'est-ce que $ titre ?. Juste les bases, ce n'est pas clair de la question et serait bon de devoir donner des exemples en fonction de la question. Pour échapper correctement aux deux matchs de $ Sujet ainsi que les valeurs de variable, j'ai ajouté une réponse qui traite des carences de toute fonction d'évacuation appliquée de remplacement préalable (à savoir le problème de la double échappée) .


5 Réponses :


5
votes
  1. Les évasions sont nécessaires
  2. addslashes n'est pas suffisant
  3. preg_quote échappe trop

    voir cette démo .

    Comme Mario a commenté, vous pouvez utiliser addcslashes ($ str, "\\ $") .


0 commentaires

0
votes

Malheureusement, il n'y a pas de moyen générique de le faire, mais addslashes devrait suffire dans la plupart des cas.

Pour une sécurité maximale, vous pouvez utiliser le $ {1} syntaxe. Par exemple xxx

si vous voulez vraiment être totalement de balle , utilisez une fonction de remplacement de rappel avec Preg_replace_callback () . La chaîne renvoyée à partir de la fonction de rappel est entièrement utilisée, car vous n'avez donc pas à vous soucier de mélanger la syntaxe de remplacement avec du texte normal.

exemple avec Preg_replace_callback () : xxx


4 commentaires

Preg_replace_callback () semble être une bonne solution. Une idée de la manière de passer d'autres variables, telles que le titre URL + à la fonction de rappel?


Utilisez une méthode au lieu d'une fonction comme votre rappel et placez les variables supplémentaires dont vous avez besoin comme propriétés de l'objet. Ensuite, fournissez votre rappel à Preg_replace_callback () Comme Array ($ CallbackObj, 'CallbackMethodName')


@TIKE: Vous pouvez également utiliser la version paresseuse avec une expression / e comme chaîne de remplacement pour les tirer de la portée locale.


@Atike: quelque chose comme prg_replace ("/(..)(....)/ e", '"$ 1". $ URL. "$ 2"', $ src) - ok, maintenant que Je le regarde; C'est vraiment terrible. Mais serait un raccourci vers l'approche de rappel.



0
votes

Vous n'avez pas fourni d'exemple, alors j'ai compilé un seul. La solution de travail que j'ai proposée consiste à utiliser une fonction de rappel simple: xxx pré>

résultat: p> xxx pré>

La fonction de rappel est un tel appelé fonction anonyme docs em> sup> a > Ce qui facilite la modification du code en place. P>

au cas où vous auriez besoin de plus souvent, vous pouvez mettre cela dans une fonction de votre propre, probablement de le rendre plus réévalué. Vous pouvez même aller jusqu'à présent et créer votre propre modèle pour remplacer les correspondances et les variables de sous-groupe. Pour examiner {\ 1} code> signifie correspondant à la correspondance de Sous-Pattern 1, {2} code> pour la deuxième variable. Envelopper cela dans une fonction de son propre: p>

Call \4 \" $me http://example.com/ Make it Complex \4url
        ^ problem, not in input.


12 commentaires

C'est une bonne solution aussi. Je l'utiliserais pour un code simple ou un code unique, et Preg_replace_callback avec le rappel de la méthode pour des remplacements ou un code plus complexes qui doivent être maintenus pendant un moment.


En fait, je viens de voir mon code est cassé si $ sujette contient $ . Je joue un peu, ce que j'ai écrit sur ce que l'évasion de Regex n'inclut pas $ .


Oh, je n'ai pas attrapé ça. Quel malheur :(


@Francisavila: Oui, d'une manière ou d'une autre;) Et je ne pouvais pas y travailler avec le modificateur E enfin, alors j'ai également ajouté un exemple de rappel.


Je n'ai jamais vu que fonction () utilise () {} Syntaxe avant. Est-ce une caractéristique PHP 5.3? Pouvez-vous fournir un lien vers la documentation PHP qui explique cela? Je ne peux pas en trouver un.


C'est PHP 5.3, oui. Il est documenté ici: Fonctions anonymes (PHP) .


Pourquoi tout cela lors d'une simple solution de caractère ( addcslashes ) fonctionne parfaitement? Qu'est-ce que je rate?


@Qtax: à quoi ajoute-tu les barres obliques? À $ sujet ? À $ url / $ titre ? Si vous les ajoutez à $ Sujet Vous ajoutez trop. Si vous les ajoutez à $ URL ou $ titre , vous ajoutez trop. Par exemple. Si titre contient un $ caractère par exemple. Si vous l'ajoutez à $ Sujet et contient un $ ou "\" le même problème apparaît. E Le modificateur ne fonctionne pas non plus, j'ai testé avec addcslashes car il ressemblait à une solution facile, mais cela ne fonctionne pas correctement.


Il est essayé et travaille, voyez pour vous-même. La chaîne de remplacement \\ \ € (ce ne sont pas des échappements, des caractères seulement) produisent le remplacement \ $ dans la chaîne de résultat.


@Qtax: fournir un code d'exemple de travail avec $ Sujet et substitution de $ URL et $ titre pour un remplacement indiqué dans la question ( $ Remplacer ) afin qu'il puisse être facilement édité et démontré pour quelles valeurs il ne fonctionne pas. Cela fonctionne pour certains cas et addcslashes est un bon outil pour contrôler où ajouter des barres obliques, mais elle a toujours des effets secondaires pour diverses valeurs d'entrée.


Laissez-nous Continuer cette discussion en chat


@hakre je pense que vous avez surestimé cela. $ url = 'http://example.com/'; $ title = 'le rendre complexe \ 4'; $ subjectif = 'appel \\ 4 "$ moi une URL'; $ motif = '/(.*) an () () (URL) /'; $ résultat = Preg_replace ($ motif, '\ 1'.Anddcslashes ( $ URL, '\\ $'). '\ 3'.Anddcslashes ($ titre,' \\ $ ''). '\ 4', $ sujet); donne le même résultat.



0
votes

Pour que cela soit évident, on échappe à toutes les références de redevances potentielles dans le paramètre code> de remplacement code> de Preg_replace () code>, utilisez une fonction:

$subject = preg_replace(
    $pattern,
    '\1'.preg_quote_replacement($url).'\3'.preg_quote_replacement($title).'\4',
     $subject
);


0 commentaires

0
votes

Vous devez utiliser PATTLES PRÉPARÉES . Cela fonctionne comme des déclarations préparées dans SQL:

Pattern::inject("\1@url\2@url\3", ['url' => $input]);


0 commentaires