|
|
|
| Добрый день уважаемые господа.
Столкнулся с задачей: есть новости, в которых могут встречаться теги простого форматирования (а, b, strong, i и пр.) нужно усеч этот текст для представления на главной странице и добавляется ссылка "читать дальше".
Проблема в том, что если просто делать substr() разрез может попасть на тег вроде:
Это просто пример <stro|ng>жирного<strong> текста
|
| - предполагаемый разрез
Чтобы этого не случилось, я делаю поиск следующей позиции, где выравнивается баланс открытых и закрытых тегов ("<" и ">") вот как:
// Получение позиции в строке, после символа $l, где закрываются
// ранее открытые теги, это накладывает условия на форматирование новостей
function correct_length($str, $l) {
$balance = 0;
$strlen = strlen($str);
$result = $strlen;
for($i=1; $i<=$strlen; $i++) {
if(substr($str, $i, 1)=='<') $balance++;
if(substr($str, $i, 1)=='>') $balance--;
if(($i>=$l) && ($balance==0)) {
$result = $i+1;
break;
}
}
return $result;
}
|
Это хорошо работает для не закрываемых тегов, вроде img, но для парных работает неверно:
Это просто пример <strong>|жирного<strong> текста
| .
Я пока вижу одно решение - составить список возможных для новостей тегов и морфологически разбирать весь текст считая баланс "<" и ">" и самих тегов "<a>" и "</a>" и т.д.
Но может есть другие варианты.. может кто-то может предложить.
P.S. думал над следующим вариантом: вырезать все теги, узнать на какое слово попал разрез, потом искать это слово в исходном тексте и резать по нему. Но это не всегда будет работать. | |
|
|
|
|
|
|
|
для: Wyfinger
(28.11.2009 в 03:03)
| | Лучше вообще очистить текст от тегов, затем отрезать необходимое, ведь тег может быть и в начале текста, причем несколько, и вложенных. | |
|
|
|
|
|
|
|
для: sim5
(28.11.2009 в 05:43)
| | Лучше всего вставлять в новость специальный тег - разделитель краткого и полного представления, тогда все будет здорово, только придется вручную переписать уже имеющиеся новости.
Но это один вариант, предложение с анализом тегов тоже эффективно, тогда можно будет сразу вырезать потенциально опасные теги (хотя зачем?, если все новости пишу я..).
В общем если есть мысли - высказывайтесь. | |
|
|
|
|
|
|
|
для: Wyfinger
(28.11.2009 в 08:45)
| | <p>абвгд <b>иклмн опрст <i>юфцх.... далее обрезали. Какой смысл в тегах? Коротко от новости, единственный нужный тег, это ссылка на всю новость. | |
|
|
|
|
|
|
|
для: sim5
(28.11.2009 в 09:04)
| | Это мне понравилось, буду в превью новости выводить часть текста без форматирования. | |
|
|
|
|
|
|
|
для: sim5
(28.11.2009 в 05:43)
| | Наверно наоборот лучше... Сначала обрезать, потом очистить. Обрезать и в SQL можно, если по пробелам. | |
|
|
|
|
|
|
|
для: Николай2357
(28.11.2009 в 11:39)
| | Да собственно без разницы, единственно, что чистить меньше, главное убрать их. Не понимаю к чему они нужны, и ради чего такая заморочка. | |
|
|
|
|
|
|
|
для: Wyfinger
(28.11.2009 в 03:03)
| |
<?php
function getTextWithoutHtmlTags( $text )
{
$reg = '<[A-z\/]*>';
$text = eregi_replace($reg, "", $text);
return $text;
}
$textHtml = "<p>простой текст простой текст</p> простой текст простой текст простой текст <strong>простой текст</strong>";
$text = getTextWithoutHtmlTags( $textHtml );
$text = trim( substr($text,0,50) ) . '...';
echo $text;
?>
|
| |
|
|
|
|
|
|
|
для: Jackkum
(28.11.2009 в 21:16)
| | А так если?
<?php
function getTextWithoutHtmlTags( $text )
{
$reg = '<[A-z\/]*>';
$text = eregi_replace($reg, "", $text);
return $text;
}
$textHtml = '<p style="color:red">простой текст простой текст</p> простой текст простой текст простой текст <strong>простой текст</strong>';
$text = getTextWithoutHtmlTags( $textHtml );
$text = trim( substr($text,0,50) ) . '...';
echo $text;
?>
|
| |
|
|
|
|
|
|
|
для: Николай2357
(28.11.2009 в 22:09)
| | preg_....
А разве strip_tags не справится с этой задачей? | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 05:47)
| | Ну это не мой скрипт, я просто показал, что ничего не выйдет, если в тегах будут стили.
Впрочем strip_tags() действительно не справится с поставленной задачей. | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 08:53)
| | Странно, а у мой strip_tags справляется:
<?
$textHtml = '<p style="color:red">простой текст простой текст</p> простой текст простой текст простой текст <strong>простой текст</strong>';
echo strip_tags($textHtml);
|
и полученный исходник:
простой текст простой текст простой текст простой текст простой текст простой текст | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 09:14)
| | А если текст такой:
<?
$textHtml = '<p style="color:red">простой текст простой текст</p>простой текст простой текст простой текст <strong>простой текст</strong>';
|
| |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 09:17)
| | А чем второй отличается от первого? Ну получите текстпростой вмето текст простой | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 09:23)
| | Вот именно... А надо оно? | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 09:27)
| | Ну вы извените, если с дури клеить все слова в кучу, то это ваши проблемы, а не разработчиков РНР.
Тем более, что без применения вырезки, это также будет читаться на странице слитно, что говорит о том, что верстальщик идиот, либо малограмотный. | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 09:29)
| | Взгляните пожалуйста на исходник этой страницы...
Вообще все это решается довольно просто:
<?
function getTextWithoutHtmlTags($text)
{
$tags = array(
"\n",
'</p>',
'</P>',
'<br>',
'<br />',
'<BR>',
'</td>',
'</TD>',
'</div>' ,
'</DIV>' ,
);
$n = array_fill(0, count($tags), ' ');
$text = str_replace($tags, $n, $text);
return nl2br(strip_tags($text));
}
| Это на все случаи жизни, можно верхний регистр и не принимать в расчет. Но многие визивиг-редакторы именно в таком формате и выдают html...
А вы говорите - идиоты. | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 09:51)
| | Вот такое:
может только человек по собственному недосмотру допустить.
У меня всегда были проблемы с орфографией, и я привык проводить работу над ошибками, если отдаю кому либо документ. Пенять на редактор, это значит наплевать на свою работу. ) | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 09:57)
| | А причем тут разрыв тега? Новости часто (очень часто) добавляются через админ-панель. А в админ-панели часто (очень часто) используются визивиг-редакторы. А они часто (очень часто) не ставят пробелов или прерносов строк после тегов <p></p> <br> <div></div> и так далее. Так что работу над ошибками должен делать скрипт. А strip_tags() в чистом виде не справится. Вот и. | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 10:07)
| | Если вам охота проводить работу над чужими ошибками, пожалуйста, я ничего не имею против. ;-)
Я бы такой редактор просто выкинул бы в помойку, нафик мне нужны лишние проблемы. Либо, если уже мне так надо, исправил бы редактор так, что бы он вставлял теги по человечески. Знаете, проблему можно найти даже на ровном месте, а если подстраиваться под редакторы, которые мягко сказать некорректные, то вы не страницы будет отдавать пользователю, а заниматься разборами каждой мелочи, в то время когда более важная работа требуется. | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 10:18)
| | Зря Вы так... Практически все визивиг редакторы, которые основаны на JS выдают такой результат. В остальном они чудесно справляются со своими обязанностями. И я не думаю, что это некорректные редакторы, просто это особенности технологии.
Исправлять такой редактор нет никакого смысла, и тем более это ни как не сократит время, что бы заняться более важной работой. Писать свой, используя другой подход... То да конечно. Но вряд ли копикстартер станет это делать.
А проблема решается несколькими строчками...
Впрочем я тоже ничего не имею против, у каждого свой подход :) Мне это тоже не очень то по душе. | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 10:28)
| | Я не привык пенять на редакторы, и не пользуюсь в написании визуальными редакторами. И если редатор у меня будет косячить, то я его просто исправлю или выкину. А допускать ошибки на странице, надеяь на то, что пользователи поймут, что это не я балбес, а такой редактор, это ну я даже и не знаю слов, коими бы это можно было назвать.
Я вам не даю обязательных рекомендаций, поступайте как хотите. Считаете что и так сойдет, ссылаясь на огрехи редактора, да заради бога ;-) | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 10:34)
| | Да почему же это огрехи то... Иногда специально, что бы уменьшить вес html код пишется в одну строку. Какие же это огрехи? Какие же это ошибки?
Не согласный я. :) | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 10:46)
| | Если вы напишите код в одну строку, наплевав на проблеы, то это что? Это ваш баг или редактора? | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 10:48)
| | Пробелы как раз и не нужны в таких тегах как <br>, <p> и особенно <div>. Даже вредно бывает. Переносы - да, для читабельности. Но не пробелы. Не хочу я на них плевать, я их ставить не всегда то хочу. Особенно в вап версиях. | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 10:59)
| | Что вы говорите?! Даже и не знал, что "разорванный" тег брвузер примет за проблел. Акститесь, Николай :)
Эффективным лечением может быть только одно лечение, когда лечится не следствие, а причина. Мне больше добавить нечего. | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 11:02)
| | Ну что Вы такое говорите... Какой разорванный тег? Или Вы назовете этод код невалидным?
<p style="color:red">простой текст простой текст</p>простой текст<div>простой текст</div>простой текст <strong>простой текст</strong>
|
А именно он будет обработан криво strip_tags() в чистом виде, применительно к данной задаче. И это не следствие никакое. И даже не болезнь. И в лечении не нуждается. Это нормальный, валидный код, который нужно подобающим образом обработать и вывести... | |
|
|
|
|
|
|
|
для: Николай2357
(29.11.2009 в 11:34)
| | А, вы о стыках тега и текста. Валидный, но некчемный ) | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 12:15)
| | Ну да, не очень кчемный :) Но факт есть факт - визивиги его именно так и генерят зачастую. | |
|
|
|
|
|
|
|
для: sim5
(29.11.2009 в 11:02)
| | О чем спорите то, способов то много, можно просто подправить рег. выражение добавить в шаблон и другие символы... :) | |
|
|
|
|
|
|
|
для: Wyfinger
(28.11.2009 в 03:03)
| |
<?php
function cutStr($str, $lenght = 100) {
$str = strip_tags($str);
if (strlen($str) >= $lenght) {
$wrap = wordwrap($str, $lenght, "~");
$str_cut = substr($wrap, 0, strpos($wrap, "~"));
$str_cut .= ' ...';
return $str_cut;
} else {
$str_cut = $str . ' ...';
return $str_cut;
}
}
?>
|
| |
|
|
|
|
|
|
|
для: mihdan
(30.11.2009 в 16:55)
| | Чтобы не обрезать теги
<?php
function breakword ($txt,$len,$delim='\s;,.!?:#') {
$txt = preg_replace_callback ("#(</?[a-z]+(?:>|\s[^>]*>)|[^<]+)#mi"
,create_function('$a'
,'static $len = '.$len.';'
.'$len1 = $len-1;'
.'$delim = \''.str_replace("#","\\#",$delim).'\';'
.'if ("<" == $a[0]{0}) return $a[0];'
.'if ($len<=0) return "";'
.'$res = preg_split("#(.{0,$len1}+(?=[$delim]))|(.{0,$len}[^$delim]*)#ms",$a[0],2,PREG_SPLIT_DELIM_CAPTURE);'
.'if ($res[1]) { $len -= strlen($res[1])+1; $res = $res[1];}'
.'else { $len -= strlen($res[2]); $res = $res[2];}'
.'$res = rtrim($res);/*preg_replace("#[$delim]+$#m","",$res);*/'
.'return $res;')
,$txt);
while (preg_match("#<([a-z]+)[^>]*>\s*</\\1>#mi",$txt)) {
$txt = preg_replace("#<([a-z]+)[^>]*>\s*</\\1>#mi","",$txt);
}
return $txt;
}
?>
|
| |
|
|
|
|
|
|
|
для: mihdan
(02.12.2009 в 16:26)
| | А вот это обязательно надо было - текст хелпер-функции в строковый литерал совать?
Его ж не прочтешь нормально!
Вот зачем этот выпендреж на ровном месте? | |
|
|
|
|
|
|
|
для: Trianon
(02.12.2009 в 16:36)
| | Ему статус не позволяет писать проще | |
|
|
|