PHP ancak html etiketlerini koruyarak htmlentities

6 Cevap php

Ben html varlıkları içine bir dize tüm metinleri dönüştürmek istiyorum ama bu örnek için, HTML etiketlerini koruyarak:

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

Bu tercüme edilmelidir:

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

herhangi bir fikir?

6 Cevap

Sen yazışmalar karakterin listesini alabilirsiniz => htmlentities , with the function get_html_translation_table tarafından kullanılan varlık; Bu kodu göz önünde bulundurun:

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

(You might want to check the second parameter to that function in the manual -- maybe you'll need to set it to a value different than the default one)

Size böyle bir şey elde edeceksiniz:

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)

Şimdi, istemediğiniz yazışmalarınında kaldırın:

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

Listeniz, şimdi, tüm yazışmalar karakteri vardır = kodlamak istemiyorum birkaç karakter dışında Htmlentites tarafından kullanılan> varlık.

Ve şimdi, sadece anahtarları ve değerleri listesini çıkarmak zorunda:

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

Ve, son olarak, değiştirme yapmak için str_replace kullanabilirsiniz:

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

Ve sen olsun:

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

Hangi istediğini gibi görünüyor ;-)


Edit : well, except for the encoding problem (damn UTF-8, I suppose -- I'm trying to find a solution for that, and will edit again)

Dakika sonra ikinci düzenleme çift: görünüyor size str_replace :-( çağırmadan önce, utf8_encode $search listesinde kullanmak zorunda olacak

Hangi böyle bir şey kullanmak demektir:

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

array_keys için çağrı ve çağrısı arasında str_replace.

Ve bu sefer, gerçekten ne istediğini almalısınız:

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


And here is the full portion of 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);

Ve tam çıkış:

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)

This time, it should be ok ^^
It doesn't really fit in one line, is might not be the most optimized solution ; but it should work fine, and has the advantage of allowing you to add/remove any correspondance character => entity you need or not.

Eğlenin!

Korkunç verimli, ama çalışıyor olmayabilir

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

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

Bu kabul edilen yanıt sürümü optimize edilmiştir.

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

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

Bir çözümleyici hiçbir çözüm kısa tüm durumlarda doğru olacak. Sevgiler iyi bir örnektir:

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

ama aynı zamanda desteklemek istiyorum:

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

: Eğer gibi çıkıp istediğiniz yere

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

Soru: Eğer HTML inşa ÖNCE kodlama yapabilir. Diğer bir deyişle böyle bir şey yapabilirsiniz:

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

Bunu yapabiliyorsanız kendinizi keder bir sürü tasarruf edeceğiz. Eğer yapamıyorsanız, sen <> kodlama atlamak için bir yol gerekir, ve "(yukarıda açıklandığı gibi), ya da sadece tüm kodlamak, ve sonra geri alın (örn. replace('&lt;', '<'))

Bu çok zarif bir şekilde bu sorunu çözer Ben sadece yazdığım bir fonksiyonudur:

Her şeyden önce, HTML etiketleri sonra htmlentities () kalan her substring üzerinde çalıştırılır ve bundan sonra orijinal HTML etiketleri böylece HTML etiketleri hiçbir değişim içerisinde sonuçlanan eski konumuna eklenir olacak, dize elde edilecektir. :-)

Eğlenin:

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

bflesch cevabını dayanarak, ben less than sign, greater than sign ve single quote veya {[(4) içeren dize yönetmek için bazı değişiklikler yaptım }].

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



Example of use:

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

Çıktı:

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)



You can pass any ent flag according to the htmlentities manual