На сегодня алгоритм выглядит так:
$text='Тут текст';
$brlen=50;
$len=mb_strlen($text);
$chars_cnt=$cur_pos=0;
$no_br=array('textarea');#,'script'
$br=array('br');
$br_len=mb_strlen('­');
while($cur_pos<$len)
{
if(preg_match('#^<([a-z0-9]+)[^>]*>#',mb_substr($text,$cur_pos),$m)>0)
{
if(in_array($m[1],$no_br))
{
$chars_cnt=0;
$cur_pos=strpos($text,'</'.$m[1].'>',$cur_pos)+mb_strlen($m[1])+3;
}
else
{
if(in_array($m[1],$br))
$chars_cnt=0;
$cur_pos+=mb_strlen($m[0]);
}
continue;
}
if(preg_match("#^(\t|\r|\n|\s| |\-|­)+#",mb_substr($text,$cur_pos),$m)>0)
{
$chars_cnt=0;
$cur_pos+=mb_strlen($m[0]);
continue;
}
if(preg_match("/^&[#a-z0-9]{1,10};/",mb_substr($text,$cur_pos),$m)>0)
$cur_pos+=mb_strlen($m[0]);
if(++$chars_cnt>=$brlen)
{
$text=substr_replace($text,'­',mb_strwidth(mb_substr($text,0,$cur_pos)),0);
$chars_cnt=0;
$cur_pos+=$br_len;
$len+=$br_len;
}
++$cur_pos;
}
Как видно, очень ресурсоемко. К сожалению я не смог придумать ничего лучше Прошу помочь. Однако, следует учитывать следующие особенности задачи:
1. Переносить слова нужно именно при помощи спецсимвола ­ - поскольку для пользователей с разными размерами мониторов, строки должны переносится по-разному.
2. Замена регуляркой типа [a-z0-9]{50} - невозможна. Поскольку последовательность 111111111<a href="3">1111111111</a>111111 также непрерывна.
3. Пункт 2 невозможен еще и по той причине, что если встречается спецсивол типа " , его нельзя разрывать т.е. нельзя вставить ­ вовнутрь ".
4. Внутри тега textarea такая замена длинных строк не нужна.