Jump to content
  • 0

Обрезка строки


alexandr.coder
 Share

Question

Надо обрезать строку php. Я спросил у одного знакомого. Он сказал что режет функция wordwrap. Но ничего не работает. Как можно обрезать строку, чтобы осталось заданное количество символов. Причем код не должен резать строку на середине слова. Он должен дойти до конца слова и обрезать уже не на середине, а на конце.

Link to comment
Share on other sites

25 answers to this question

Recommended Posts

  • 0

substr() - режет строку посимвольно

wordwrap() - из перевода ясно что это перенос слов а не обрезание строки...

касательно пробелов... вы можете сделать функцию которая будет брать кусок начиная с скажем 200 символа и заканчивая 220 искать первое вхождение пробела, и дальше уже резать целиком всю строку на 200+число до первого вхождения, довольная простая и быстрая функция...

Edited by stars
Link to comment
Share on other sites

  • 0
substr() - режет строку посимвольно

wordwrap() - из перевода ясно что это перенос слов а не обрезание строки...

касательно пробелов... вы можете сделать функцию которая будет брать кусок начиная с скажем 200 символа и заканчивая 220 искать первое вхождение пробела, и дальше уже резать целиком всю строку на 200+число до первого вхождения, довольная простая и быстрая функция...

Смотря для кого. Я не понял, как сделать обрезку на конце слова.

Link to comment
Share on other sites

  • 0
Смотря для кого. Я не понял, как сделать обрезку на конце слова.

function foo($str, $leng, $dir){
settype($leng, "int");
settype($dir, "bool");
settype($dir, "string");
while($str[$leng]!=" "){
$leng+=(($dir)?1:-1);
}
return substr($str, 0, $leng);
}

Ну вот сел и за 4 минуты написал, причём хотите ищите пробел выше заданной длинны или ниже, просто работать было лень.

Edited by XprogeR
Link to comment
Share on other sites

  • 0

/^(\W+?\s+){5}/i

Ну вот так вот можно выделить 5 слов, а чтобы по количеству символов резать, я вот так придумал

<?
$maxsize=20; //Число отрезаемых символов
$a='Эту фразу мы постараемся разрезать так, чтобы разрез пришёлся на конец слова';
$z2=array();
$length=-1;
$z=explode(' ',$a);
$zsize=sizeof($z);
for ($_ = 0; $_ < $zsize; $_++)
{
$length+=mb_strlen($z[$_],'UTF-8')+1; //+1 - пробел
$z2[$_][0]=$z[$_];
$z2[$_][1]=$length;
}
$out='';
foreach ($z2 as $words)
{
$out.=$words[0].' ';
if ($words[1] >= $maxsize) break;
}
$out=trim($out);


echo $out."\n";
?>

Правда, я индус? :))

settype($dir, "bool");
settype($dir, "string");

А зачем так? Edited by Int
Link to comment
Share on other sites

  • 0
/^(\W+?\s+){5}/i

Ну вот так вот можно выделить 5 слов, а чтобы по количеству символов резать, я вот так придумал

<?
$maxsize=20; //Число отрезаемых символов
$a='Эту фразу мы постараемся разрезать так, чтобы разрез пришёлся на конец слова';
$z2=array();
$length=-1;
$z=explode(' ',$a);
$zsize=sizeof($z);
for ($_ = 0; $_ < $zsize; $_++)
{
$length+=mb_strlen($z[$_],'UTF-8')+1; //+1 - пробел
$z2[$_][0]=$z[$_];
$z2[$_][1]=$length;
}
$out='';
foreach ($z2 as $words)
{
$out.=$words[0].' ';
if ($words[1] >= $maxsize) break;
}
$out=trim($out);


echo $out."\n";
?>

Правда, я индус? :))

А зачем так?

Ещё и какой индус, зачем столько действий? В моем варианте просто ищет ближайший пробел от максимальной длины, которую задал пользователь, тоесть

если обычный текст, не более 20 итераций, код очень быстрый. По поводу вашего вопроса привожу в строк для того чтоб не было ошибок, так как число не массив, а строка да, привожу к булевому типу по привычке да бы быть уверенным что у меня за типы.

Edited by XprogeR
Link to comment
Share on other sites

  • 0

О, как любопытно :) здесь разгорелось соревнование :) Позволю себе добавить маленький недостаток: вы ищите «пробел», но про него изначально не упоминалось, слово не всегда заканчивается пробелом, там может выть любой знак препинания, или это могут быть скобки, кавычки и т.д.

Link to comment
Share on other sites

  • 0
О, как любопытно ^_^ здесь разгорелось соревнование :) Позволю себе добавить маленький недостаток: вы ищите «пробел», но про него изначально не упоминалось, слово не всегда заканчивается пробелом, там может выть любой знак препинания, или это могут быть скобки, кавычки и т.д.

Ну в таком случае он оставит этот пробел или другой знак препинания в покое и найдет пробел! =) Задача стояла именно в том чтобы найти ближайший пробел от заданной длинны и обрезать от начала и до него! =)

А если нужно чтоб и знак препинания искал и обрезал тогда нужно просто добавить ещё один параметр в котором будут указанны символы по которым обрезать и немножко расширить функционал. =)

Link to comment
Share on other sites

  • 0
вы ищите «пробел», но про него изначально не упоминалось,
Задача стояла именно в том чтобы найти ближайший пробел от заданной длинны

Читайте внимательней топик стартера,

Как можно обрезать строку, чтобы осталось заданное количество символов. Причем код не должен резать строку на середине слова. Он должен дойти до конца слова и обрезать уже не на середине, а на конце.

Перевожу: надо сделать строку заданной длины, при условии чтоб слово не обрезалось а доводилось до конца.

Как я уже говорил конец слова - это не всегда пробел. вот и всё, конечно это не сложно, просто читать задание и понимать задачи тоже очень важно чтоб по триста раз не переделывать и находить оптимальное решение.

P.s. Есть ещё вариант когда слово заканчивается концом строки(в смысле символом перевода каретки, а не полным концом EOF).

Link to comment
Share on other sites

  • 0
Читайте внимательней топик стартера,

Перевожу: надо сделать строку заданной длины, при условии чтоб слово не обрезалось а доводилось до конца.

Как я уже говорил конец слова - это не всегда пробел. вот и всё, конечно это не сложно, просто читать задание и понимать задачи тоже очень важно чтоб по триста раз не переделывать и находить оптимальное решение.

P.s. Есть ещё вариант когда слово заканчивается концом строки(в смысле символом перевода каретки, а не полным концом EOF).

EOF - End of file, строка заканчивается терминирующим нулем. Да бы не быть голословным предложите свой вариант.

function foo($str, $leng, $char_list, $dir=true, $tmp_charset="CP-1251"){
settype($leng, 'int');
settype($dir, 'bool');
settype($dir, 'string');
is_array($char_list) or trigger_error("char_list must be an array", E_USER_ERROR);
$charset = mb_detect_encoding($str);
$str = mb_convert_encoding($str, $tmp_charset, $charset);
$part_1 = substr($str, 0, $leng);
$part_2 = substr($str, $leng);
$part_leng = ($dir)?strlen($part_2):strlen($part_2);
foreach ($char_list as $end_char){
$end_char = mb_convert_encoding($end_char, $tmp_charset, mb_detect_encoding($end_char));
$part_leng = ($dir)?(strpos($part_2, $end_char)!== false && $part_leng > strpos($part_2, $end_char))?strrpos($part_2, $end_char):$part_leng:(strrpos($part_1, $end_char)!== false && $part_leng > strrpos($part_1, $end_char))?strrpos($part_1, $end_char):$part_leng;
}
$leng = ($dir)?$leng+$part_leng:$leng-$part_leng;
$str = substr($str, 0, $leng);
$str = mb_convert_encoding($str, $charset, $tmp_charset);
return $str;
}

Вот вам универсальная функция которая будет резать по заданным символам. Учитывая кодировку.

Link to comment
Share on other sites

  • 0
mb_convert_encoding срабатывает через раз ^_^ В смысле не на всех данных работает.

Чё-то не в ту степь понесло всех.

Проблема в том что стандартные функции не корректно работают с UTF-8, поэтому использовал mb_, в любом случае этот код можно легко переделать для обычных функций, и все будет гуд.

PS: Ещё не встречал корректно настроенного сервера и не рабочие функции в одном флаконе.

Link to comment
Share on other sites

  • 0
EOF - End of file, строка заканчивается терминирующим нулем.

Да, вы правы тут я с терминологией погорячился...

Да бы не быть голословным предложите свой вариант.

Не хотелось бы из теоретика наблюдателя превращаться в обсуждаемого ^_^ но видать увы придётся.

Кодировку внутри преобразовывать не вижу смысла, это отдельная задача других функций.

Если есть замечания кроме того, что я использовал preg_match(), с удовольствием выслушаю.

<?php

function crop_string($string,$length) {

if (strlen($string)>$length) {
$temp_string = substr($string, 0, $length);

while (preg_match('/[а-яa-z0-9]/i',$string{$length})) {
$temp_string.=$string{$length};
$length++;
}
return $temp_string;
} ELSE {
return $string;
}
}

$strochka = <<<STR
Ну в таком случае он оставит этот пробел или другой знак препинания в покое и найдет пробел! =) Задача стояла именно в том чтобы найти ближайший пробел от заданной длинны и обрезать от начала и до него! =)
А если нужно чтоб и знак препинания искал и обрезал тогда нужно просто добавить ещё один параметр в котором будут указанны символы по которым обрезать и немножко расширить функционал. =)
STR;

Echo $strochka."<hr>";

Echo crop_string($strochka, 207);
?>

Чё-то тут ничего не понятно. А почему нельзя сделать что-то типа

^.{10}[^\s]*

где 10==нужное количество символов?

сразу видно программиста образованного :) - да работает отлично !

Link to comment
Share on other sites

  • 0
сразу видно программиста образованного ^_^ - да работает отлично !

Не, всё плохо на самом деле. Строка ведь может быть и меньше 10 символов. Поэтому надо делать {0,10}. Ну и еще что-то мог не учесть. Ну тут главное в этом деле наводку дать, а там уже всё допиливается.

Link to comment
Share on other sites

  • 0
Не, всё плохо на самом деле. Строка ведь может быть и меньше 10 символов. Поэтому надо делать {0,10}. Ну и еще что-то мог не учесть. Ну тут главное в этом деле наводку дать, а там уже всё допиливается.

ну это мелочи, главное лаконичная суть ясна, остальное надфилем можно обточить ^_^

Link to comment
Share on other sites

  • 0

для начала bb коды должны обрабатываться и переводиться в html вид, а у вас из примера видно что этого не происходит.

введенный текст в форму: текст

после обработки html вид: <strong>текст</strong>

Edited by rus
Link to comment
Share on other sites

  • 0
Подскажите пожалуйста

Что нужно сделать что бы bb теги закрывались?

Стоит лимит символов на 800

т.е. получается вот так Рейтинг...

что нужно сделать, что бы тег закрывался?

Спасибо.

Я бы сделал так:

Допустим, есть текст

Вот это [b]такой[/b] текст, в [b]нём присутствуют[/b] всяческие bb-коды

1. Обрезаем строку.

Вот это [b]такой[/b] текст, в [b]нём прису

2. Заменяем все «парные» bb-теги

Вот это <b>такой</b> текст, в [b]нём прису

3. Ищем непарные bb-теги и заменяем их, добавляя в конец недостаюшие закрывающие

Вот это <b>такой</b> текст, в <b>нём прису</b>

Как-то так...

Link to comment
Share on other sites

  • 0

А можно подробнее про второй и третий пункт?

Вот что нашел по форматированию

function bb_tags($text) 
{
// Создаем массив bb-тегов
$bb = array(
'[B]',
'[/B]',
'[I]',
'[/I]',
'[S]',
'[/S]',
'[U]',
'[/U]'
);
// Создаем массив тегов HTML
$tag = array(
'<b>',
'</b>',
'<i>',
'</i>',
'<s>',
'</s>',
'<u>',
'</u>'
);
// Заменяем элемент первого на элемент второго массива соответственно
return str_ireplace($bb, $tag, $text);
}

Edited by den_in
Link to comment
Share on other sites

  • 0

сделал следующим образом:

$patterns[0] = "[b]";
$patterns[1] = "[/b]";
$patterns[2] = "[u]";
$patterns[3] = "[/u]";


$replacements[3] = "<b>";
$replacements[2] = "</b>";
$replacements[1] = "<u>";
$replacements[0] = "</u>";
echo preg_replace($patterns, $replacements, $descr);

но пока что не могу встроить

preg_replace($patterns, $replacements, $descr);

вот в эту строку

$descr = substr(strip_tags($descr), 0, strpos(strip_tags($descr), ' ', 800)).'...';

Link to comment
Share on other sites

  • 0

Тут ещё стоит учитывать жадность. Насколько я помню, по умолчанию preg_replace — жадный, так что такой вариант может работать совершенно неверно, но я могу и ошибаться.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy