Эта функция отлично работает, однако, если html-элемент найден, она остановится там, где будет отсчет 45-го символа, независимо от того, что ломает html-элемент. Как я могу сделать исключение для этого? Я предполагаю какое-то регулярное выражение, но не уверен, что лучше в этом случае.
public function fts_custom_trim_words( $text, $num_words = 45, $more ) {
! empty( $num_words ) && 0 !== $num_words ? $more = __( '...' ) : '';
$text = nl2br( $text );
$text = strip_shortcodes( $text );
// Add tags that you don't want stripped.
$text = strip_tags( $text, '<strong><br><em><i><a>' );
$words_array = preg_split( "/[\n\r\t ]+/", $text, $num_words + 1, PREG_SPLIT_NO_EMPTY );
$sep = ' ';
if ( count( $words_array ) > $num_words ) {
array_pop( $words_array );
$text_string = implode( $sep, $words_array );
$text = $text_string . $more;
} else {
$text = implode( $sep, $words_array );
}
return wpautop( $text );
}
Сейчас что-то подобное сломает....
@aeocreative и я на церемонии награждения журнала Sarasota Magazine «Дом года»! Я сфотографировал дом для @tracee_murphy < a href="https://www.instagram.com/trade"...
С чего начинается строка и чем она должна заканчиваться?
Я надеялся, что если он найдет html-элемент, он будет ждать его конца, прежде чем добавлять...
Может быть, что-то вроде regex101.com/r/KxyVTT/1 Это должно пропускать элементы, за некоторыми исключениями, и может пропускать некоторые химические формулы и математические уравнения, но если предположить, что все в порядке?
Строка является динамической и может содержать любое количество ссылок, поэтому в идеале мне нужно что-то, если она найдет ссылку перед остановкой, обязательно включите остальную часть ссылки перед остановкой... Я видел множество так называемых решений, но ни одно из них работает на меня.






У вас есть два варианта:
1) Использовать PHP stript_tags() (простой вариант)
Это вернет обычный текст, любые теги в строке больше не будут работать (например, <a>, <strong>, <li> и т. д. Реализация будет выглядеть так:
$text = strip_tags($text);
2) Используйте предложение @Chris Harrison здесь: Ограничение текстовой строки PHP, НЕ включая теги html?
Этот вариант сохраняет теги, но потребует перестройки вашей функции, чтобы сделать ее более сложной.
Обновлено:
Возможно, это не то, что вы ищете, но я создал простое решение, которое разбивает строку на фрагменты, а затем проверяет каждый фрагмент. Это не так точно, как вариант 2, но требует намного меньше кода.
function truncate($string, $maxChars) {
// Explode input string on a character
$stringParts = explode(' ', $string);
$finalString = '';
$charCount = 0;
foreach ($stringParts as $part) {
if ($charCount <= $maxChars) {
$charCount += strlen(strip_tags($part));
$finalString .= (' ' . $part);
} else {
return $finalString;
}
}
}
Спасибо, я думаю, что № 2 - это ответ для меня, я проверю его и вернусь к вам.
Строка является динамической и может содержать любое количество ссылок, поэтому в идеале мне что-то нужно, если она найдет ссылку перед остановкой, обязательно включите остальную часть ссылки перед остановкой, ни одно из ваших решений не работает для меня, к сожалению.
это может работать, непроверено, но оно должно работать и делать то, что вы просили...
этот первый - обрезать @ количество символов
<?php
function truncate_by_characters ( $s, $l = 45, $e = '...' )
{
$sl = strlen ( $s );
$ns = 0;
$cr = 0;
$rs = '';
preg_match_all ( '/<[^>]*>[^<]+</[^>]*>|<(?!/)[^>]*>/', $s, $m, PREG_OFFSET_CAPTURE | PREG_SET_ORDER );
foreach ( $m as $v )
{
if ( ( $v[0][1] - $ns ) >= $l )
{
break;
}
$ss = substr ( $s, $ns, ( $v[0][1] - $ns ) );
$cr += strlen ( $ss );
$rs .= $ss . $v[0][0];
$ns = ( $v[0][1] + strlen ( $v[0][0] ) );
}
if ( $cr < $l )
{
if ( ( $ns + ( $l - $cr ) ) > $sl )
{
$ts = substr ( $s, $ns, ( $sl - $ns ) );
}
else
{
$ts = substr ( $s, $ns, ( $l - $cr ) );
}
for ( $x = ( strlen ( $ts ) - 1 ); $x >= 0; $x -= 1 )
{
$z = array ( "\t", "\r", "\n", " ", "\0", "\x0B" );
if ( in_array ( $ts[$x], $z ) )
{
$rs .= substr ( $ts, 0, $x );
break;
}
}
}
return $rs . $e;
}
$truncate_text = 'This <img src = "" alt = ""> function works great however if a <a href = "http://.com/page.html?test=1">html element</a> is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';
//$truncate_text = 'This function works great however if a html element is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';
$truncate_characters = 45;
$truncate_ending = '...';
echo truncate_by_characters ( $truncate_text, $truncate_characters, $truncate_ending );
?>
ПРИМЕЧАНИЕ. Функция, указанная выше, работает, однако функция, указанная ниже, в настоящий момент не дает никаких результатов.
этот второй - обрезать @ количество слов
<?php
function truncate_by_words ( $s, $l = 45, $e = '...' )
{
$sl = strlen ( $s );
$ns = 0;
$tw = 0;
$rs = '';
preg_match_all ( '/<[^>]*>[^<]+</[^>]*>|<(?!/)[^>]*>/', $s, $m, PREG_OFFSET_CAPTURE | PREG_SET_ORDER );
foreach ( $m as $v )
{
$ss = substr ( $s, $ns, ( $v[0][1] - $ns ) );
$wf = str_word_count ( $ss, 2 );
$wc = count ( $wf );
if ( ( $tw + $wc ) >= $l )
{
$mw = 1;
foreach ( $wf AS $wp => $wv )
{
if ( ( $tw + $mw++ ) == $l )
{
$ss = substr ( $s, $ns, ( $wp - $ns ) );
$rs .= $ss . $wv;
$ns = ( $wp + strlen ( $wv ) );
$tw = $l;
break;
}
}
}
$tw += $wc;
$rs .= $ss . $v[0][0];
$ns = ( $v[0][1] + strlen ( $v[0][0] ) );
}
if ( $tw < $l )
{
$ss = substr ( $s, $ns, ( $sl - $ns ) );
$wf = str_word_count ( $ss, 2 );
$wc = count ( $wf );
if ( ( $tw + $wc ) <= $l )
{
$rs .= $ss;
}
else
{
$mw = 1;
foreach ( $wf AS $wp => $wv )
{
if ( ( $tw + $mw++ ) == $l )
{
$ss = substr ( $ss, 0, $wp );
$rs .= $ss . $wv;
break;
}
}
}
}
return $rs . $e;
}
$truncate_text = 'This <img src = "" alt = ""> function works great however if a <a href = "http://.com/page.html?test=1">html element</a> is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';
//$truncate_text = 'This function works great however if a html element is found it will stop where the 45th character count is no matter what, which breaks the html element. How can I make an exception for this? I\'m guessing some kind of regex but not sure what is best in this case.';
$truncate_words = 35;
$truncate_ending = '...';
echo truncate_by_words ( $truncate_text, $truncate_words, $truncate_ending );
?>
Хорошо, первый для количества символов работает отлично, однако я бы очень хотел, чтобы слова работали, если это возможно, прямо сейчас функция слов не работает. Также вы можете рассмотреть такие теги, как @foo_underscore, иначе _underscore тоже останется несвязанным. Большое спасибо за вашу помощь здесь.
Просто вдогонку :)
@ 10826537 не могли бы вы помочь :)
Вы хотите, чтобы ссылка была кликабельной или текстовым после полосы?