我需要截断文字才能获得预览。预览是〜N
字符的文本前缀(但不是更多),它不应该在中间分割单词。
preview("aaa", 10) = "aaa" preview("a b c", 10) = "a b c" preview("aaa bbb", 5) = "aaa" preview("a b ccc", 3) = "a b"
我按如下方式编写了一个函数:
def preview(s:String, n:Int) = if (s.length <= n) s else s.take(s.lastIndexOf(' ', n))
你会改变或修复它吗?
现在我正在考虑如何处理文本单词由一个或多个空格(包括\n
,\t
等)而不是单个空格分隔的情况。你将如何改进处理这种情况的功能?
答案 0 :(得分:8)
以下内容如何:
def preview(s: String, n: Int) = if (s.length <= n) {
s
} else {
s.take(s.lastIndexWhere(_.isSpaceChar, n + 1)).trim
}
此功能将:
n
,返回字符串(无需预览)n + 1
第一个字符中的最后一个空格字符(这将指示最后一个世界是否被拆分,好像它不是n + 1
将是空格字符,否则是非 - 空格字符)并将字符串带到此点注意:isSpaceChar的使用不仅会提供对空间的支持,还会提供对新行或段落的支持,这是我相信您所追求的(并且您可以将其替换为isWhitespace
if你需要更多扩展的单词分隔符。)
答案 1 :(得分:2)
我建议下一个:
- 更新 -
def ellipsize(text : String, max : Int): String = {
def ellipsize0(s : String): String =
if(s.length <= max) s
else {
val end = s.lastIndexOf(" ")
if(end == -1) s.take(max)
else ellipsize0(s.take(end))
}
ellipsize0("\\s+".r.replaceAllIn(text, " "))
}
或您的(已修改):
def preview(str : String, n : Int) = {
(s : String) => if (s.length <= n) s else s.take(s.lastIndexOf(' ', n))
}.apply( "\\s+".r.replaceAllIn(str, " "))
答案 2 :(得分:1)
这个怎么样
def preview(s:String, n:Int) =
if (s.length <= n) s
else s.take(n).takeWhile(_ != ' ')
在此处试试:http://scalafiddle.net/console/a05d886123a54de3ca4b0985b718fb9b
答案 3 :(得分:1)
这似乎有效:
// find the last word that is not split by n, then take to its end
def preview(text: String, n: Int): String =
text take (("""\S+""".r findAllMatchIn text takeWhile (_.end <= n)).toList match {
case Nil => n
case ms => ms.last.end
})
另一种选择(双关语),但不喜欢所有空格的输入:
text take (("""\S+""".r findAllMatchIn text takeWhile (m => m.start == 0 || m.end <= n)).toList.last.end min n)
外延上:
object Previewer {
implicit class `string preview`(val text: String) extends AnyVal {
// find the last word that is not split by n, then take to its end
def preview(n: Int): String =
text take (("""\S+""".r findAllMatchIn text takeWhile (_.end <= n)).toList match {
case Nil => n
case ms => ms.last.end
})
}
}
看起来很漂亮:
class PreviewTest {
import Previewer._
@Test def shorter(): Unit = {
assertEquals("aaa", "aaa" preview 10)
}
@Test def spacey(): Unit = {
assertEquals("a b c", "a b c" preview 10)
}
@Test def split(): Unit = {
assertEquals("abc", "abc cba" preview 5)
}
@Test def onspace(): Unit = {
assertEquals("a b", "a b cde" preview 3)
}
@Test def trimming(): Unit = {
assertEquals("a b", "a b cde" preview 5)
}
@Test def none(): Unit = {
assertEquals(" " * 5, " " * 8 preview 5)
}
@Test def prefix(): Unit = {
assertEquals("a" * 5, "a" * 10 preview 5)
}
}