用省略号截断字符串的理想方法 [英] Ideal method to truncate a string with ellipsis
问题描述
我相信我们所有人都在 Facebook 状态(或其他地方)上看到过省略号,然后点击显示更多",结果只有 2 个左右的字符.我猜这是因为懒惰的编程,因为肯定有一个理想的方法.
I'm sure all of us have seen ellipsis' on Facebook statuses (or elsewhere), and clicked "Show more" and there are only another 2 characters or so. I'd guess this is because of lazy programming, because surely there is an ideal method.
我的将细长字符 [iIl1]
视为半个字符",但这并没有解决省略号在几乎不隐藏任何字符时看起来很傻的问题.
Mine counts slim characters [iIl1]
as "half characters", but this doesn't get around ellipsis' looking silly when they hide barely any characters.
有没有理想的方法?这是我的:
Is there an ideal method? Here is mine:
/**
* Return a string with a maximum length of <code>length</code> characters.
* If there are more than <code>length</code> characters, then string ends with an ellipsis ("...").
*
* @param text
* @param length
* @return
*/
public static String ellipsis(final String text, int length)
{
// The letters [iIl1] are slim enough to only count as half a character.
length += Math.ceil(text.replaceAll("[^iIl]", "").length() / 2.0d);
if (text.length() > length)
{
return text.substring(0, length - 3) + "...";
}
return text;
}
语言并不重要,但被标记为 Java,因为这是我最感兴趣的内容.
Language doesn't really matter, but tagged as Java because that's what I'm mostly interested in seeing.
推荐答案
我喜欢让细"字符算作半个字符的想法.简单且很好的近似.
I like the idea of letting "thin" characters count as half a character. Simple and a good approximation.
然而,大多数省略号的主要问题是(恕我直言)它们在中间截断了单词.这是一个考虑字边界的解决方案(但没有深入研究像素数学和 Swing-API).
The main issue with most ellipsizings however, are (imho) that they chop of words in the middle. Here is a solution taking word-boundaries into account (but does not dive into pixel-math and the Swing-API).
private final static String NON_THIN = "[^iIl1\.,']";
private static int textWidth(String str) {
return (int) (str.length() - str.replaceAll(NON_THIN, "").length() / 2);
}
public static String ellipsize(String text, int max) {
if (textWidth(text) <= max)
return text;
// Start by chopping off at the word before max
// This is an over-approximation due to thin-characters...
int end = text.lastIndexOf(' ', max - 3);
// Just one long word. Chop it off.
if (end == -1)
return text.substring(0, max-3) + "...";
// Step forward as long as textWidth allows.
int newEnd = end;
do {
end = newEnd;
newEnd = text.indexOf(' ', end + 1);
// No more spaces.
if (newEnd == -1)
newEnd = text.length();
} while (textWidth(text.substring(0, newEnd) + "...") < max);
return text.substring(0, end) + "...";
}
算法测试如下所示:
这篇关于用省略号截断字符串的理想方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!