2011-10-21 2 views
0

Iam tente de remplacer Esperluettes sur mon html sidewide utilisant preg_replace, mais le problème est qu'il casse en ligne javascript & & ou javascript URL comme? Page = Test & id = 1php preg_replace regex préanalyse

Maintenant, j'ai cette code, qui fonctionne

$amp_replace = array(); 
$amp_replace[0] = '/(?<=\s)&(?!&)(?!#?[a-z0-9]+;)/'; 
$amp_replace[1] = '/(?<!&)&(?=\s)/'; 
$skin = preg_replace($amp_replace, '&amp;', $skin); 

Remplace les esperluettes lorsque l'espace est à gauche ou à droite. ne remplacez pas quand 2 ampersand dans une rangée (pour javascript) ou en suivant par l'entité html.

Mais je trouve ici une logique plutôt inutile. Il ne remplace pas non plus ampersands si son test comme &.

Comme je ne suis pas expert en regex, cela m'a pris un certain temps déjà, alors j'ai pensé que je demander de l'aide ici encore une fois.

Ne serait-il pas préférable de remplacer simplement toutes les ampères-ondes sinon dans les balises de script javascript? J'ai déjà essayé, mais pas vraiment de succès

Est-ce que quelqu'un sait comment je pourrais l'archiver? Merci

+0

Comment ces '&' y arriver en premier lieu? Ne devriez-vous pas plutôt régler ce problème? –

+0

Contenu soumis par l'utilisateur. Je sais que je pourrais le réparer en écrivant dans chacun de mes fichiers php pour corriger les sorties d'esperluette. Mais dans ce cas particulier, je n'ai pas besoin de ça. Comme mon codage pp devient assez grand, je veux plutôt avoir une déclaration globale pour cela. Regardez à travers tout mon HTML et remplacez si ce n'est pas dans les balises de script – Basti

Répondre

0

Pourquoi ne pas quelque chose de simple comme:

$html = preg_replace('/([^&])&([^&])/', '$1&amp;$2', $html);

Si vous voulez éviter de remplacer tous esperluette intérieur Javascript, ajouter préanalyse/derrière pour les balises de script, ou découpez d'abord le document sur les balises de script, et exécutez uniquement le remplacement sur les parties non-script.

$html = preg_split('/<\/?script>/', $html); 
foreach ($html as $k => $v) { 
    if ($piece[0] == "<") { 
    $html[$k] = preg_replace('/([^&])&([^&])/', '$1&amp;$2', $v); 
    } else { 
    $html[$k] = "<script>" . $html[$k] . "</script>"; 
} 

Cela nécessitera des modifications si vos balises de script ont des attributs.

Si vous êtes en train de désinfecter le contenu de l'utilisateur, vous pouvez utiliser les outils déjà disponibles. Voir HTML Purifier

+0

Le $ var var est mon html analysé, donc je regarde à travers mon trou html, cela ne fonctionnera pas dans mon cas malheureusement. comme ci-dessus fonctionne mais je le veux plus simple, comme remplacer tous et si pas dans les balises de script. Je sais que je pourrais simplement faire un remplacement dans chacune de mes fonctions, mais je préfèrerais seulement écrire cette fois – Basti

+0

Également essayé avec les balises de script, mais il semble que je ne comprends jamais, soit erreur ou il ne remplacera pas – Basti

+0

la méthode split, merci :) – Basti

1

Si vous voulez juste convertir « & » en contenu et éviter les balises (par exemple: les valeurs d'attributs)
et éviter les blocs de script, quelque chose comme ci-dessous fonctionnera pour la plupart des occurences.
Cependant, il convient de noter que les valeurs d'attribut doivent également être converties.
Et cela nécessite beaucoup plus de travail.

échantillon de travail http://www.ideone.com/9MhCq

<?php 

$html=<<<EOD 
<some &ta&g> S&P &&more; and &some; <more> &notme; 
    && &#209; &#xa92F; 
<script flavor?> 
    val && this & this 
</script> 
& 
EOD; 

$rxent = '(?:&(?:[A-Za-z_:][\w:.-]*|\#(?:[0-9]+|x[0-9a-fA-F]+));)'; 

$rxtag = 
'< 
(?: 
    \?php\s+.*?\? 
    | (?: 
     (?: 
      (?:script|style)\s* 
     | (?:script|style)\s+(?:".*?"|\'.*?\'|[^>]*?)+\s* 
     )> .*? </(?:script|style)\s* 
    ) 
    | (?: 
     /?[A-Za-z_:][\w:.-]*\s*/? 
     | [A-Za-z_:][\w:.-]*\s+(?:".*?"|\'.*?\'|[^>]*?)+\s*/? 
     | !(?:DOCTYPE.*?|--.*?--) 
    ) 
) 
> 
'; 

$rxmain = "~(?xs:((?:$rxtag)+) | ((?!$rxent)&))~"; 


print "$html\n\n"; 

$html = preg_replace_callback($rxmain, 'fixamp_cb', $html); 

print "$html\n"; 

function fixamp_cb($matches) { 
    # Return tags and script blocks unchanged. 
    if (isset($matches[1]) && $matches[1]) 
     return $matches[1]; 
    return '&amp;'; 
} 

?>