Domanda

voglio convertire tutti i testi in una stringa in entità HTML, ma preservando i tag HTML, ad esempio questo:

<p><font style="color:#FF0000">Camión español</font></p>

dovrebbe essere tradotto in questo modo:

<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>

tutte le idee?

È stato utile?

Soluzione

È possibile ottenere l'elenco di carattere corrispondenze => un'entità usata da htmlentities , con la funzione get_html_translation_table ; considerare questo codice:

$list = get_html_translation_table(HTML_ENTITIES);
var_dump($list);

(si potrebbe voler controllare il secondo parametro a tale funzione nel manuale - forse è necessario impostarlo su un valore diverso da quello predefinito)

Si otterrà qualcosa di simile:

array
  ' ' => string '&nbsp;' (length=6)
  '¡' => string '&iexcl;' (length=7)
  '¢' => string '&cent;' (length=6)
  '£' => string '&pound;' (length=7)
  '¤' => string '&curren;' (length=8)
  ....
  ....
  ....
  'ÿ' => string '&yuml;' (length=6)
  '"' => string '&quot;' (length=6)
  '<' => string '&lt;' (length=4)
  '>' => string '&gt;' (length=4)
  '&' => string '&amp;' (length=5)

Ora, rimuovere le corrispondenze non si vuole:

unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

Il tuo elenco, ora, ha tutto il carattere corrispondenze => un'entità usata da htmlentites, tranne i pochi caratteri non si desidera codificare.

E ora, non resta che estrarre l'elenco di chiavi e valori:

$search = array_keys($list);
$values = array_values($list);

E, infine, è possibile utilizzare str_replace per fare la sostituzione:

$str_in = '<p><font style="color:#FF0000">Camión español</font></p>';
$str_out = str_replace($search, $values, $str_in);
var_dump($str_out);

E si ottiene:

string '<p><font style="color:#FF0000">Cami&Atilde;&sup3;n espa&Atilde;&plusmn;ol</font></p>' (length=84)

che assomiglia a quello che si voleva; -)


Edit: bene, tranne per il problema di codifica (maledetto UTF-8, suppongo - Sto cercando di trovare una soluzione per questo, e permetterà di modificare di nuovo)

Seconda modifica paio di minuti dopo: sembra dovrete usare utf8_encode sulla lista $search, prima di chiamare str_replace: - (

Il che significa usare qualcosa di simile a questo:

$search = array_map('utf8_encode', $search);

Tra la chiamata alla array_keys e la chiamata a str_replace.

E, questa volta, si dovrebbe davvero ottenere ciò che si voleva:

string '<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>' (length=70)


E qui è la parte piena di codice:

$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

$search = array_keys($list);
$values = array_values($list);
$search = array_map('utf8_encode', $search);

$str_in = '<p><font style="color:#FF0000">Camión español</font></p>';
$str_out = str_replace($search, $values, $str_in);
var_dump($str_in, $str_out);

E l'output completo:

string '<p><font style="color:#FF0000">Camión español</font></p>' (length=58)
string '<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>' (length=70)

Questa volta, dovrebbe essere ok ^^
Essa non si adatta in realtà in una sola riga, è potrebbe non essere la soluzione più ottimizzata; ma dovrebbe funzionare bene, e ha il vantaggio di permettere di aggiungere / rimuovere qualsiasi carattere corrispondenza => entità è necessario o meno.

Buon divertimento!

Altri suggerimenti

Potrebbe non essere terribilmente efficace, ma funziona

$sample = '<p><font style="color:#FF0000">Camión español</font></p>';

echo htmlspecialchars_decode(
    htmlentities($sample, ENT_NOQUOTES, 'UTF-8', false)
  , ENT_NOQUOTES
);

Questa versione è ottimizzata della risposta accettata.

$list = get_html_translation_table(HTML_ENTITIES);
unset($list['"']);
unset($list['<']);
unset($list['>']);
unset($list['&']);

$string = strtr($string, $list);

No soluzione a breve di un parser sta per essere corretto per tutti i casi. Il vostro è un buon esempio:

<p><font style="color:#FF0000">Camión español</font></p>

, ma si fa anche si vuole sostenere:

<p><font>true if 5 < a && name == "joe"</font></p>

dove vuoi che a venire fuori come:

<p><font>true if 5 &lt; a &amp;&amp; name == &quot;joe&quot;</font></p>

Domanda: Si può fare la codifica prima di costruire il codice HTML. In altre parole, si può fare qualcosa di simile:

"<p><font>" + htmlentities(inner) + "</font></p>"

Potrai risparmiare un sacco di dolore, se si può fare. Se non è possibile, avrete bisogno di un certo modo di saltare la codifica <,>, e "(come descritto sopra), o semplicemente codificare tutto, e poi annullarla (ad es. replace('&lt;', '<'))

Questa è una funzione che ho appena scritto che risolve questo problema in un modo molto elegante:

Prima di tutto, i tag HTML verrà estratto dalla stringa, quindi htmlentities () viene eseguito su ogni stringa rimanente e dopo che i tag HTML originali saranno inseriti nella loro vecchia posizione conseguente nessun alternanza dei tag HTML . : -)

Buon divertimento:

function htmlentitiesOutsideHTMLTags ($htmlText)
{
    $matches = Array();
    $sep = '###HTMLTAG###';

    preg_match_all("@<[^>]*>@", $htmlText, $matches);   
    $tmp = preg_replace("@(<[^>]*>)@", $sep, $htmlText);
    $tmp = explode($sep, $tmp);

    for ($i=0; $i<count($tmp); $i++)
        $tmp[$i] = htmlentities($tmp[$i]);

    $tmp = join($sep, $tmp);

    for ($i=0; $i<count($matches[0]); $i++)
        $tmp = preg_replace("@$sep@", $matches[0][$i], $tmp, 1);

    return $tmp;
}

In base alla risposta di bflesch , ho fatto alcune modifiche per gestire stringa contenente less than sign, greater than sign e single quote o double quotes.

function htmlentitiesOutsideHTMLTags ($htmlText, $ent)
{
    $matches = Array();
    $sep = '###HTMLTAG###';

    preg_match_all(":</{0,1}[a-z]+[^>]*>:i", $htmlText, $matches);

    $tmp = preg_replace(":</{0,1}[a-z]+[^>]*>:i", $sep, $htmlText);
    $tmp = explode($sep, $tmp);

    for ($i=0; $i<count($tmp); $i++)
        $tmp[$i] = htmlentities($tmp[$i], $ent, 'UTF-8', false);

    $tmp = join($sep, $tmp);

    for ($i=0; $i<count($matches[0]); $i++)
        $tmp = preg_replace(":$sep:", $matches[0][$i], $tmp, 1);

    return $tmp;
}



Esempio di utilizzo:

$string = '<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>';
$string_entities = htmlentitiesOutsideHTMLTags($string, ENT_QUOTES | ENT_HTML401);
var_dump( $string_entities );

L'uscita è:

string '<b>Is 1 &lt; 4?</b>&egrave;<br><i>&quot;then&quot;</i> <div style="some:style;"><p>gain some <strong>&euro;</strong><img src="/some/path" /></p></div>' (length=150)



È possibile passare qualsiasi ent flag secondo il htmlentities manuale

soluzione one-linea con NO funzione di tabella di conversione o personalizzato richiesto:

So che questa è una vecchia questione, ma di recente ho dovuto importare un sito statico in un sito WordPress e ha dovuto superare questo problema:

Questa è la mia soluzione che non richiede giocherellare con tabelle di conversione:

htmlspecialchars_decode( htmlentities( html_entity_decode( $string ) ) );

quando applicato alla stringa del PO:

<p><font style="color:#FF0000">Camión español</font></p>

uscita:

<p><font style="color:#FF0000">Cami&oacute;n espa&ntilde;ol</font></p>

quando applicato alla stringa di Luca:

<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>

uscita:

<b>Is 1 < 4?</b>&egrave;<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>&euro;</strong><img src="/some/path" /></p></div>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top