Frage

Ich möchte alle Texte in einer Zeichenfolge in HTML -Entitäten konvertieren, aber die HTML -Tags beispielsweise beispielsweise dies beibehalten:

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

sollte in dieses übersetzt werden:

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

irgendwelche Ideen?

War es hilfreich?

Lösung

Sie können die Liste der Korrespondenzen erhalten Zeichen => Entität von verwendet von htmlentities, mit der Funktion get_html_translation_table ; Betrachten Sie diesen Code:

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

(Möglicherweise möchten Sie den zweiten Parameter für diese Funktion im Handbuch überprüfen. Möglicherweise müssen Sie ihn auf einen anderen Wert einstellen, der sich als die Standardeinstellung unterscheidet.)

Es wird dir so etwas bekommen:

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)

Entfernen Sie nun die Korrespondenz, die Sie nicht wollen:

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

Ihre Liste hat jetzt alle Korrespondenzzeichen => Entität, die von HTMLentiten verwendet wird, mit Ausnahme der wenigen Zeichen, die Sie nicht codieren möchten.

Und jetzt müssen Sie nur die Liste der Schlüssel und Werte extrahieren:

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

Und schließlich können Sie Str_Replace verwenden, um den Ersatz durchzuführen:

$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);

Und du bekommst:

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

Was sieht aus wie was du wolltest ;-)


Bearbeiten: Nun, bis auf das Codierungsproblem (verdammt UTF-8, nehme ich an-ich versuche dafür eine Lösung zu finden und werde wieder bearbeiten)

Zweite bearbeiten ein paar Minuten danach: Es scheint, dass Sie verwenden müssen utf8_encode auf der $search Liste, bevor Sie anrufen str_replace :-(

Was bedeutet, so etwas zu verwenden:

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

Zwischen dem Anruf zu array_keys und der Anruf zu str_replace.

Und diesmal solltest du wirklich bekommen, was du wolltest:

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


Und hier ist der volle Teil des Code:

$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);

Und die volle Ausgabe:

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)

Diesmal sollte es in Ordnung sein ^^
Es passt nicht wirklich in eine Zeile, ist möglicherweise nicht die optimierteste Lösung. Es sollte jedoch gut funktionieren und haben den Vorteil, dass Sie ein Korrespondenzzeichen => Entität hinzufügen/entfernen können, das Sie benötigen oder nicht.

Habe Spaß !

Andere Tipps

Vielleicht nicht besonders effizient sein, aber es funktioniert

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

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

Dies ist eine optimierte Version der akzeptierten Antwort.

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

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

Keine Lösung, die ein Parser nicht mehr in allen Fällen korrekt ist. Ihr ist ein guter Fall:

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

Aber möchten Sie auch unterstützen:

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

wo du willst, dass es herauskommt als:

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

Frage: Können Sie die Codierung vornehmen, bevor Sie die HTML erstellen? Mit anderen Worten können so etwas wie:

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

Sie werden sich viel Trauer ersparen, wenn Sie das können. Wenn Sie nicht können, benötigen Sie eine Möglichkeit, Codierung <,> und "(wie oben beschrieben) zu überspringen oder einfach alles zu codieren und dann rückgängig zu machen (z. replace('&lt;', '<'))

Dies ist eine Funktion, die ich gerade geschrieben habe, die dieses Problem auf sehr elegante Weise löst:

Zunächst werden die HTML -Tags aus der Zeichenfolge extrahiert, dann wird HTMLentities () an jedem verbleibenden Substring ausgeführt, und danach werden die ursprünglichen HTML -Tags an ihrer alten Position eingefügt, was zu keiner Abwechslung der HTML -Tags führt. :-)

Habe Spaß:

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;
}

Basierend auf der Antwort von bflessch, Ich habe einige Änderungen vorgenommen, um die Zeichenfolge zu verwalten, die enthält less than sign, greater than sign und single quote oder 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;
}



Beispiel der Verwendung:

$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 );

Ausgabe ist:

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)



Sie können jeden passieren ent flag laut dem HTMLENTITY -Handbuch

Einzeilungslösung ohne Übersetzungstabelle oder benutzerdefinierte Funktion erforderlich:

Ich weiß, dass dies eine alte Frage ist, aber ich musste kürzlich eine statische Seite in eine WordPress -Site importieren und dieses Problem überwinden:

Hier ist meine Lösung, die nicht mit Übersetzungstabellen fummelt erfordert:

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

Bei der Anlage auf die String des OP:

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

Ausgang:

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

Bei Anwendung auf Lucas 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>

Ausgang:

<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>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top