programing

PHP의 htmlentities이지만 html 태그는 유지

nasanasas 2021. 1. 7. 08:04
반응형

PHP의 htmlentities이지만 html 태그는 유지


문자열의 모든 텍스트를 html 엔티티로 변환하지만 HTML 태그는 유지하고 싶습니다. 예를 들면 다음과 같습니다.

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

다음과 같이 번역해야합니다.

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

어떤 아이디어?


htmlentities함수를 사용하여 에서 사용하는 문자 => 엔티티의 대응 목록을 얻을 수 있습니다 get_html_translation_table. 이 코드를 고려하십시오.

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

(매뉴얼에서 해당 기능에 대한 두 번째 매개 변수를 확인하고 싶을 수 있습니다. 기본 값과 다른 값으로 설정해야 할 수도 있습니다.)

다음과 같은 결과를 얻을 수 있습니다.

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)

이제 원하지 않는 서신을 제거하십시오.

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

이제 목록에는 인코딩하지 않으려는 몇 가지 문자를 제외하고 htmlentites에서 사용하는 모든 대응 문자 => 엔티티가 있습니다.

이제 키와 값 목록을 추출하기 만하면됩니다.

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

마지막으로 str_replace를 사용하여 교체 할 수 있습니다.

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

그리고 당신은 :

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

당신이 원했던 것처럼 보입니다 ;-)


편집 : 글쎄, 인코딩 문제를 제외하고 (젠장 UTF-8, 나는 생각한다-그것에 대한 해결책을 찾으려고 노력하고 있으며 다시 편집 할 것입니다)

이후 분의 두 번째 편집 커플 : 보일지 당신이 사용해야합니다 utf8_encode$search호출하기 전에, 목록 str_replace:-(

이는 다음과 같은 것을 사용하는 것을 의미합니다.

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

에 대한 통화 array_keys와에 대한 통화 사이 str_replace.

그리고 이번에는 정말 원하는 것을 얻어야합니다.

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


다음은 코드의 전체 부분입니다.

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

그리고 전체 출력 :

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)

이번에는 괜찮을 텐데요 ^^
한 줄에 맞지 않고, 가장 최적화 된 솔루션이 아닐 수도 있습니다. 그러나 그것은 잘 작동 할 것이고, 당신이 필요로하는 모든 대응 문자 => 엔티티를 추가 / 제거 할 수 있다는 장점이 있습니다.

즐기세요!


별로 효율적이지 않을 수도 있지만 작동합니다.

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

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

이것은 허용되는 답변의 최적화 된 버전입니다.

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

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

파서가 부족한 솔루션은 모든 경우에 적합하지 않습니다. 당신의 것이 좋은 경우입니다.

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

하지만 다음을 지원 하시겠습니까?

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

다음과 같이 나오길 원하는 위치 :

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

질문 : HTML을 빌드하기 전에 인코딩을 할 수 있습니까? 즉, 다음과 같이 할 수 있습니다.

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

그렇게 할 수 있다면 많은 슬픔을 덜어 줄 것입니다. 당신은, 당신은 인코딩 건너 몇 가지 방법이 필요합니다 할 수없는 경우 (전술 한 바와 같이), 또는 단순히 모든 인코딩하고, <,>, 그리고 "그것을 실행 취소 (예. replace('&lt;', '<'))


이것은 매우 우아한 방식으로이 문제를 해결하는 방금 작성한 함수입니다.

First of all, the HTML tags will be extracted from the string, then htmlentities() is executed on every remaining substring and after that the original HTML tags will be inserted at their old position thus resulting in no alternation of the HTML tags. :-)

Have fun:

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

Based on the answer of bflesch, I did some changes to manage string containing less than sign, greater than sign and single quote or 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;
}



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

Output is:

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


one-line solution with NO translation table or custom function required:

i know this is an old question, but i recently had to import a static site into a wordpress site and had to overcome this issue:

here is my solution that does not require fiddling with translation tables:

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

when applied to the OP's string:

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

output:

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

when applied to Luca's 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>

output:

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

ReferenceURL : https://stackoverflow.com/questions/1364933/htmlentities-in-php-but-preserving-html-tags

반응형