Unione di due espressioni regolari per troncare Parole in stringhe
Domanda
Sto cercando di venire con la seguente funzione che tronca la stringa di parole intere (se possibile, altrimenti si dovrebbe troncare a caratteri):
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));
}
Ecco alcuni test:
// 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, '...');
Entrambi lavorano come è, se lascio cadere il secondo preg_replace()
ottengo il seguente:
Iñtërnâtiônàlizætiøn_and_then_the_quick_brown_fox_jumped_overly_the_lazy_dog e un giorno il cane pigro gobba la povero giù volpe fino alla sua morte ....
Non è possibile utilizzare substr()
perché funziona solo a livello di byte e non hanno accesso a mb_substr()
bancomat, ho fatto diversi tentativi per unire la seconda regex con il primo, ma senza successo.
Si prega di aiuto S.M.S., ho lottato con questo per quasi un'ora.
EDIT: Mi dispiace, sono stato sveglio per 40 ore e ho spudoratamente perso questo:
$string = preg_replace('~^(.{1,' . intval($limit) . '})(?:\s.*|$)?~su', '$1', $string);
Ancora, se qualcuno ha un regex più ottimizzato (o uno che ignora lo spazio finale) si prega di condividere:
"Iñtërnâtiônàlizætiøn and then "
"Iñtërnâtiônàlizætiøn_and_then_"
EDIT 2:? Non riesco ancora a sbarazzarsi del trailing spazio bianco, di aiuto qualcuno può darmi una mano
EDIT 3: Va bene, nessuno dei mie modifiche hanno funzionato, venivo ingannare dalle RegexBuddy - forse dovrei lasciare questo per un altro giorno e dormire un po 'ora. Off per oggi.
Soluzione
Forse posso darvi una mattinata felice dopo una lunga notte di incubi RegExp:
'~^(.{1,' . intval($limit) . '}(?<=\S)(?=\s)|.{'.intval($limit).'}).*~su'
ebollizione giù:
^ # 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)
Si può sempre aggiungere il |$
alla fine del (?=\s)
ma dal momento che il codice è già stato verificato che la lunghezza della stringa è più lunga della $limit
, non mi sentivo quel caso sarebbe neccesary.
Altri suggerimenti
Hai pensato di usare wordwrap? ( http://us3.php.net/wordwrap )