Intereting Posts

PHP substr, но сохраняйте теги HTML?

Мне интересно, есть ли элегантный способ обрезать какой-то текст, но, будучи осведомленным в тегах HTML?

Например, у меня есть эта строка:

$data = '<strong>some title text here that could get very long</strong>'; 

И, допустим, мне нужно вернуть / вывести эту строку на странице, но она должна быть не более X символов. Скажем, 35 ​​для этого примера.

Затем я использую:

 $output = substr($data,0,20); 

Но теперь я получаю:

 <strong>some title text here that 

которые, как вы видите, закрывают сильные теги, отбрасываются, тем самым нарушая отображение HTML.

Есть ли способ обойти это? Также обратите внимание, что в строке можно указать несколько тегов:

 <p>some text here <strong>and here</strong></p> 

Несколько месяцев назад я создал специальную функцию, которая является решением вашей проблемы.

Вот функция:

 function substr_close_tags($code, $limit = 300) { if ( strlen($code) <= $limit ) { return $code; } $html = substr($code, 0, $limit); preg_match_all ( "#<([a-zA-Z]+)#", $html, $result ); foreach($result[1] AS $key => $value) { if ( strtolower($value) == 'br' ) { unset($result[1][$key]); } } $openedtags = $result[1]; preg_match_all ( "#</([a-zA-Z]+)>#iU", $html, $result ); $closedtags = $result[1]; foreach($closedtags AS $key => $value) { if ( ($k = array_search($value, $openedtags)) === FALSE ) { continue; } else { unset($openedtags[$k]); } } if ( empty($openedtags) ) { if ( strpos($code, ' ', $limit) == $limit ) { return $html."..."; } else { return substr($code, 0, strpos($code, ' ', $limit))."..."; } } $position = 0; $close_tag = ''; foreach($openedtags AS $key => $value) { $p = strpos($code, ('</'.$value.'>'), $limit); if ( $p === FALSE ) { $code .= ('</'.$value.'>'); } else if ( $p > $position ) { $close_tag = '</'.$value.'>'; $position = $p; } } if ( $position == 0 ) { return $code; } return substr($code, 0, $position).$close_tag."..."; } с function substr_close_tags($code, $limit = 300) { if ( strlen($code) <= $limit ) { return $code; } $html = substr($code, 0, $limit); preg_match_all ( "#<([a-zA-Z]+)#", $html, $result ); foreach($result[1] AS $key => $value) { if ( strtolower($value) == 'br' ) { unset($result[1][$key]); } } $openedtags = $result[1]; preg_match_all ( "#</([a-zA-Z]+)>#iU", $html, $result ); $closedtags = $result[1]; foreach($closedtags AS $key => $value) { if ( ($k = array_search($value, $openedtags)) === FALSE ) { continue; } else { unset($openedtags[$k]); } } if ( empty($openedtags) ) { if ( strpos($code, ' ', $limit) == $limit ) { return $html."..."; } else { return substr($code, 0, strpos($code, ' ', $limit))."..."; } } $position = 0; $close_tag = ''; foreach($openedtags AS $key => $value) { $p = strpos($code, ('</'.$value.'>'), $limit); if ( $p === FALSE ) { $code .= ('</'.$value.'>'); } else if ( $p > $position ) { $close_tag = '</'.$value.'>'; $position = $p; } } if ( $position == 0 ) { return $code; } return substr($code, 0, $position).$close_tag."..."; } не function substr_close_tags($code, $limit = 300) { if ( strlen($code) <= $limit ) { return $code; } $html = substr($code, 0, $limit); preg_match_all ( "#<([a-zA-Z]+)#", $html, $result ); foreach($result[1] AS $key => $value) { if ( strtolower($value) == 'br' ) { unset($result[1][$key]); } } $openedtags = $result[1]; preg_match_all ( "#</([a-zA-Z]+)>#iU", $html, $result ); $closedtags = $result[1]; foreach($closedtags AS $key => $value) { if ( ($k = array_search($value, $openedtags)) === FALSE ) { continue; } else { unset($openedtags[$k]); } } if ( empty($openedtags) ) { if ( strpos($code, ' ', $limit) == $limit ) { return $html."..."; } else { return substr($code, 0, strpos($code, ' ', $limit))."..."; } } $position = 0; $close_tag = ''; foreach($openedtags AS $key => $value) { $p = strpos($code, ('</'.$value.'>'), $limit); if ( $p === FALSE ) { $code .= ('</'.$value.'>'); } else if ( $p > $position ) { $close_tag = '</'.$value.'>'; $position = $p; } } if ( $position == 0 ) { return $code; } return substr($code, 0, $position).$close_tag."..."; } 

Здесь DEMO: http://sandbox.onlinephpfunctions.com/code/899d8137c15596a8528c871543eb005984ec0201 (нажмите «Выполнить код», чтобы проверить, как он работает).

Используя @newbieuser его функцию, у меня была такая же проблема, как @ pablo-pazos, что она была (не) нарушена, когда $ limit попал в html-тег (в моем случае <br /> на r)

Исправлено с некоторым кодом

 if ( strlen($code) <= $limit ){ return $code; } $html = substr($code, 0, $limit); //We must find a . or > or space so we are sure not being in a html-tag! //In my case there are only <br> //If you have more tags, or html formatted text, you must do a little more and also use something like http://htmlpurifier.org/demo.php $_find_last_char = strrpos($html, ".")+1; if($_find_last_char > $limit/3*2){ $html_break = $_find_last_char; }else{ $_find_last_char = strrpos($html, ">")+1; if($_find_last_char > $limit/3*2){ $html_break = $_find_last_char; }else{ $html_break = strrpos($html, " "); } } $html = substr($html, 0, $html_break); preg_match_all ( "#<([a-zA-Z]+)#", $html, $result ); ...... 

substr (strip_tags ($ content), 0, 100)