如何在 golang 中椭圆截断文本?
How can I elliptically truncate text in golang?
我希望能够干净利落地剪切大于特定字符数的段落,而不需要在中间剪切一个单词。
例如:
It is a long established fact that a reader will be distracted by the
readable content of a page when looking at its layout. The point of
using Lorem Ipsum is that it has a more-or-less normal distribution of
letters, as opposed to using 'Content here, content here', making it
look like readable English.
应该变成:
It is a long established fact that a reader will be distracted by the
readable content ...
这是我想出的函数:
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
}
但它只是粗暴地切割文本。我想知道如何修改(或用更好的解决方案替换它)以便椭圆切割文本?
要根据空格等进行拆分,可以使用正则表达式:
func splitString(str string) []string {
re := regexp.MustCompile("[\s\n\t\r ]+") //split according to \s, \t, \r, \t and whitespace. Edit this regex for other 'conditions'
split := re.Split(str, -1)
return split
}
func main() {
var s = "It is a long\nestablished fact that a reader\nwill\nbe distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
var maxLen = 40
arr := splitString(s)
totalLen := 0
finalStr := ``
for _, each := range arr {
if (totalLen + len(each) > maxLen) {
fmt.Print(strings.TrimSpace(finalStr) + `...`)
break
}
totalLen += len(each)
finalStr += each + ` `
}
}
//老2
你可以做这样的事情:将你的字符串分成切片并循环遍历切片,直到你的字符串的总长度超过允许的最大长度。
var s = "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
var maxLen = 30
arr := strings.SplitAfter(s, ` `)
totalLen := 0
finalStr := ``
for _, each := range arr {
if (totalLen + len(each) > maxLen) {
fmt.Print(strings.TrimSpace(finalStr) + `...`)
break
}
totalLen += len(each)
finalStr += each
}
这是早已确立的事实...
//旧的错误答案
您必须使用字符串和切片:
var s = "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
newS := s[:30 - 3]
newS += `...`
fmt.Print(newS)
结果:It is a long established fa...
写的范围完全没有必要;就像现在一样,您的整个功能可能只是:
func truncateText(s string, max int) string {
return s[:max]
}
太简单了,甚至不应该是一个函数;但当然它也会切断你说你不想要的话。所以你可以:
func truncateText(s string, max int) string {
if max > len(s) {
return s
}
return s[:strings.LastIndex(s[:max]," ")]
}
或者如果您想使用多个字符作为单词边界而不仅仅是空格:
func truncateText(s string, max int) string {
if max > len(s) {
return s
}
return s[:strings.LastIndexAny(s[:max]," .,:;-")]
}
切片字符串可能会出现问题,因为切片使用的是字节,而不是符文。然而,射程适用于符文:
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
我希望能够干净利落地剪切大于特定字符数的段落,而不需要在中间剪切一个单词。
例如:
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English.
应该变成:
It is a long established fact that a reader will be distracted by the readable content ...
这是我想出的函数:
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
}
但它只是粗暴地切割文本。我想知道如何修改(或用更好的解决方案替换它)以便椭圆切割文本?
要根据空格等进行拆分,可以使用正则表达式:
func splitString(str string) []string {
re := regexp.MustCompile("[\s\n\t\r ]+") //split according to \s, \t, \r, \t and whitespace. Edit this regex for other 'conditions'
split := re.Split(str, -1)
return split
}
func main() {
var s = "It is a long\nestablished fact that a reader\nwill\nbe distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
var maxLen = 40
arr := splitString(s)
totalLen := 0
finalStr := ``
for _, each := range arr {
if (totalLen + len(each) > maxLen) {
fmt.Print(strings.TrimSpace(finalStr) + `...`)
break
}
totalLen += len(each)
finalStr += each + ` `
}
}
//老2
你可以做这样的事情:将你的字符串分成切片并循环遍历切片,直到你的字符串的总长度超过允许的最大长度。
var s = "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
var maxLen = 30
arr := strings.SplitAfter(s, ` `)
totalLen := 0
finalStr := ``
for _, each := range arr {
if (totalLen + len(each) > maxLen) {
fmt.Print(strings.TrimSpace(finalStr) + `...`)
break
}
totalLen += len(each)
finalStr += each
}
这是早已确立的事实...
//旧的错误答案
您必须使用字符串和切片:
var s = "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."
newS := s[:30 - 3]
newS += `...`
fmt.Print(newS)
结果:It is a long established fa...
写的范围完全没有必要;就像现在一样,您的整个功能可能只是:
func truncateText(s string, max int) string {
return s[:max]
}
太简单了,甚至不应该是一个函数;但当然它也会切断你说你不想要的话。所以你可以:
func truncateText(s string, max int) string {
if max > len(s) {
return s
}
return s[:strings.LastIndex(s[:max]," ")]
}
或者如果您想使用多个字符作为单词边界而不仅仅是空格:
func truncateText(s string, max int) string {
if max > len(s) {
return s
}
return s[:strings.LastIndexAny(s[:max]," .,:;-")]
}
切片字符串可能会出现问题,因为切片使用的是字节,而不是符文。然而,射程适用于符文:
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