Объединение двух регулярных выражений, чтобы укоренить слова в строках
Вопрос
Я пытаюсь придумать следующую функцию, которая усекает строку целым словам (если возможно, в противном случае он должен укоренить к Chars):
function Text_Truncate($string, $limit, $more = '...')
{
$string = trim(html_entity_decode($string, ENT_QUOTES, 'UTF-8'));
if (strlen(utf8_decode($string)) > $limit)
{
$string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)~su', '$1', $string);
if (strlen(utf8_decode($string)) > $limit)
{
$string = preg_replace('~^(.{' . intval($limit) . '}).*~su', '$1', $string);
}
$string .= $more;
}
return trim(htmlentities($string, ENT_QUOTES, 'UTF-8', true));
}
Вот несколько тестов:
// Iñtërnâtiônàlizætiøn and then the quick brown fox... (49 + 3 chars)
echo dyd_Text_Truncate('Iñtërnâtiônàlizætiøn and then the quick brown fox jumped overly the lazy dog and one day the lazy dog humped the poor fox down until she died.', 50, '...');
// Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_... (50 + 3 chars)
echo dyd_Text_Truncate('Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog and one day the lazy dog humped the poor fox down until she died.', 50, '...');
Они оба работают, как это, однако, если я бросил вторую preg_replace()
Я получаю следующее:
Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog и однажды ленивая собака горбала бедной лисы вниз, пока она не умерла ....
Я не могу использовать substr()
потому что он работает только на байтовом уровне, и у меня нет доступа к mb_substr()
Банкомат, я сделал несколько попыток присоединиться к второму регелесу первым, но без успеха.
Пожалуйста, помогите SMS, я борюсь с этим почти час.
Редактировать: Извините, я не проснулся 40 часов, и я бесстыдно пропустил это:
$string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)?~su', '$1', $string);
Тем не менее, если у кого-то есть более оптимизированное Regex (или тот, который игнорирует конечное пространство), пожалуйста, поделитесь:
"Iñtërnâtiônàlizætiøn and then "
"Iñtërnâtiônàlizætiøn_and_then_"
Редактировать 2: Я до сих пор не могу избавиться от конечного пробела, может ли кто-нибудь помочь мне?
Отредактируйте 3: Хорошо, ни один из моих редактиков действительно не работал, я одурачил Regexbuddy - я, вероятно, должен оставить это в другой день и немного спать. На сегодняшний день.
Решение
Возможно, я могу дать вам счастливое утро после долгой ночи кошмаров Regexp:
'~^(.{1,' . intval($limit) . '}(?<=\S)(?=\s)|.{'.intval($limit).'}).*~su'
Кипятить его:
^ # Start of String
( # begin capture group 1
.{1,x} # match 1 - x characters
(?<=\S)# lookbehind, match must end with non-whitespace
(?=\s) # lookahead, if the next char is whitespace, match
| # otherwise test this:
.{x} # got to x chars anyway.
) # end cap group
.* # match the rest of the string (since you were using replace)
Вы всегда можете добавить |$
до конца (?=\s)
Но поскольку ваш код уже проверял, что длина строки была длиннее $limit
, Я не чувствовал, что дело будет необходимым.
Другие советы
Вы думали, используя WordWrap? (http://us3.php.net/wordwrap)