Chcę, żeby na stronie głównej były wyświetlane tylko początki newsów - pierwsze 600 znaków. Problem polega na tym, że w newsach mogą być stsowane tagi bbcode:
[img][/img], [quote][/quote], [url][/url], [url=],[/url], [b][/b], [i][/i], [u][/u], [color=][/color], [br], [hr], [center][/center]
I jeśli cały tag nie zmieści się w tych 600 znakach (zacznie się, ale nie skończy), to będą komplikacje. Chyba wiadomo jakie.
Czy wie ktoś w jaki sposób się przed tym zabezpieczyć? Chciałbym, żeby było coś takiego, że jeśli nie zmieści się tag np. obrazka, to zostanie pominięty całkiem(wycięty), czyli tekst zostanie skrócony do miejsca gdzie zaczyna się ten tag. Jeśli się zmieści, to oczywiście ma zostać. Jeśli nie zmieszczą się całe tagi takie jak [b], [u], [quote] itp, to zostaną po prostu zamknięte wcześniej, zaraz po tych 600 znakach.
Wie ktoś jak takie coś zrobić?

- Rejestracja:ponad 18 lat
- Ostatnio:prawie 9 lat
- Postów:79
Generalnie w inny sposób, poza ręcznym liczeniem znaków i patrzeniem, czy rozpoczęty tag został zamknięty, nic nie zrobisz.
Czyli liczysz znaczki, każde wystąpienie '[' sprawdzasz, czy jest rozpoczęciem taga, jeśli tak to przestajesz liczenia aż do ']', sprawdzasz czy tag jest pojedynczy czy podwójny, jeśli podwójny to odkładasz go sobie na stos. Liczysz dalej, aż natkniesz się na zakończenie taga (jeśli był podwójny), zdejmujesz go wtedy za stosu, i kiczysz dalej. Jak dojdziesz do 600, to sprawdzasz czy na stosie są jeszcze jakieś tagi, jak tak, to je zamykasz i wtedy kończysz.
Oczywiście nie znaczy że masz o robić po jednej literce - pokombinuj albo z regexpami (choć nie wiem czy sensownie Ci tutaj pomogą), albo strpos(), albo różne takie. Walcz :)
Ale zagadnienie nawet ciekawe, może jak znajde chwilę wolnego to napiszę jakieś przyjemne narzędzie do tego :) Zapisuję sobie pomysł w moim małym TODO ;)

- Rejestracja:około 21 lat
- Ostatnio:około 13 lat
ucinasz 600 znaków, szukasz ostatniej pozycji [ i osobno ], jeśli pozycja [ jest późniejsza niż ostatniego ] to dodajesz na końcu ] albo ucinasz wszystko po nim i parsujesz normalnie jak to robisz przy pełnym artykule (oczywiście zadziała jeśli obsługę tego bbcode'u masz poprawnie zrobioną)

- Rejestracja:około 21 lat
- Ostatnio:około 13 lat

- Rejestracja:ponad 18 lat
- Ostatnio:prawie 9 lat
- Postów:79
Najlepsza koncpecja, jaką udało mi się wymyśleć tak na dość szybko, to to co poniżej:
//funkcja pomocnicza
//zwraca:
//nazwa tagu - jeśli jest to rozpoczęcie tagu podwojnego
//1 - jeśli to pojedynczy tag
//0 - jeśli to zwykły tekst
//-1 - jeśli to zakończenie tagu
function check_tag($s) {
if (preg_match('!^\[(img|quote|url|b|i|u|color|center)(\s*=\s*.*?)?\]$!i', $s, $match)) { //tag rozpoczynający
return $match[1];
} else if (preg_match('!^\[/(img|quote|url|b|i|u|color|center)\]$!i', $s)) { //tag kończący
return -1;
} else if (preg_match('!^\[(br|hr)\]$!i', $s)) { //tag pojedynczy
return 1;
} else { // zwykly string
return 0;
}
}
//$str - string
//$len - długość
//$type - string lub array
//$concat - string służący do łączenia poszczególnych kawałków
function strTagsCut($str, $len, $type='string', $concat='') {
static $tags = array(
'single' => array('br', 'hr'),
'double' => array('img','quote','url','b', 'i', 'u', 'color', 'center'),
);
$pat = sprintf('!(\[/?(?:%s|%s)(?:\s*=\s*.*?]*)?\])!i',
implode('|', $tags['single']),
implode('|', $tags['double'])
);
$splitted = preg_split($pat, $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
$count = 0;
$stack = array();
$new = array();
foreach ($splitted as $part) {
$tag = check_tag($part);
if (is_string($tag)) {
array_push($stack, $tag);
} else if ($tag === 0) {
$l = strlen($part);
if (($count+$l) >= $len) {
$new[] = substr($part, 0, -($count+$l-$len));
foreach (array_reverse($stack) as $el) {
$new[] = sprintf('[/%s]', $el);
}
break;
}
$count += $l;
} else if ($tag === -1) {
array_pop($stack);
}
$new[] = $part;
}
return $type=='array' ? $new : join($concat, $new);
}
Sposób użycia:
echo strTagsCut($jakis_tekst, 600);
Dzięki za kod. W sumie, to nie liczyłem, że komuś się będzie chciało całą funkcję pisać, tylko ktoś mi coś podpowie, więc naprawdę dzięki za pomoc.
Tylko dalej jest pewnien problem z tagami:
[url]http://asdasdasdasdasd[/url] i [img]http://cośtamasdasdasdasd[/img]
[url=http:/asdasdasdasdasd]nazwa linka[/url] działa dobrze, bo skraca najwyżej tekst nazwa linka, ale [url]http://www.asdasdasd.asd[/url] nie może skracać tekstu wewnątrz tagów, bo właśnie tam jest url. Da się coś z tym zrobić? Tak samo z img, bo wtedy otrzymam niepełny adres obrazka

- Rejestracja:ponad 18 lat
- Ostatnio:prawie 9 lat
- Postów:79
A może na serwer też wgrać za Ciebie? :/ IMO to już trochę się wysilić możesz sam. I tak zrobiłem dużo. Jak widzę, za dużo...
Manual trackback: http://urzenia.net/316/skracanie-tekstu/
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.