如何在 golang 中省略截断文本?

Smn*_*Smn 9 string truncate go

我希望能够干净地剪切大于一定字符数的段落,而无需在中间剪切单词。

例如:

长期以来的事实是,读者在查看页面布局时会被页面的可读内容分散注意力。使用 Lorem Ipsum 的要点在于,它具有或多或少的字母正态分布,而不是使用“此处内容,此处内容”,使其看起来像可读的英语。

应该变成:

读者会被可读内容分散注意力,这是一个长期存在的事实……

这是我想出的函数:

 func truncateText(s string, max int) string {
    if len(s) > max {
        r := 0
        for i := range s {
            r++
            if r > max {
                return s[:i]
            }
        }
    }
    return s
}
Run Code Online (Sandbox Code Playgroud)

但它只是残酷地削减了文字。我想知道如何修改(或用更好的解决方案替换它)以便以椭圆方式剪切文本?

Bur*_*dar 9

切片字符串可能会出现问题,因为切片适用于字节,而不是符文。然而,范围适用于符文:

lastSpaceIx:=-1
len:=0
for i,r:=range str {
  if unicode.IsSpace(r) {
     lastSpaceIx=i
  }
  len++
  if len>=max {
    if lastSpaceIx!=-1 {
        return str[:lastSpaceIx]+"..."
    }
    // If here, string is longer than max, but has no spaces
  }
}
// If here, string is shorter than max
Run Code Online (Sandbox Code Playgroud)


Adr*_*ian 6

所写的范围完全没有必要;就像现在一样,您的整个功能可能是:

func truncateText(s string, max int) string {
    return s[:max]
}
Run Code Online (Sandbox Code Playgroud)

这太简单了,甚至不应该是一个函数;但当然它也会切断你说你不想要的单词。所以你可以:

func truncateText(s string, max int) string {
    if max > len(s) {
        return s
    }
    return s[:strings.LastIndex(s[:max]," ")]
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您想使用多个字符作为单词边界而不仅仅是空格:

func truncateText(s string, max int) string {
    if max > len(s) {
        return s
    }
    return s[:strings.LastIndexAny(s[:max]," .,:;-")]
}
Run Code Online (Sandbox Code Playgroud)

  • @Adrian,感谢您的提示,但这有一些缺点:1.当字符串中存在换行符时给出错误。2. 当文本长度短于“max”时出现恐慌。 (7认同)
  • 字符串切片操作将字符串视为字节切片。如果字符串包含多字节字符,则 s[:max] 不是剪切它的正确位置。 (4认同)
  • 这可能不是多字节安全的。 (3认同)