diff --git a/text/gstr/gstr_convert.go b/text/gstr/gstr_convert.go
index 7c4a6add3..c358dd14e 100644
--- a/text/gstr/gstr_convert.go
+++ b/text/gstr/gstr_convert.go
@@ -9,12 +9,18 @@ package gstr
import (
"bytes"
"fmt"
- "github.com/gogf/gf/v2/util/grand"
"math"
"regexp"
"strconv"
"strings"
"unicode"
+
+ "github.com/gogf/gf/v2/util/grand"
+)
+
+var (
+ // octReg is the regular expression object for checks octal string.
+ octReg = regexp.MustCompile(`\\[0-7]{3}`)
)
// Chr return the ascii string of a number(0-255).
@@ -27,11 +33,6 @@ func Ord(char string) int {
return int(char[0])
}
-var (
- // octReg is the regular expression object for checks octal string.
- octReg = regexp.MustCompile(`\\[0-7]{3}`)
-)
-
// OctStr converts string container octal string to its original string,
// for example, to Chinese string.
// Eg: `\346\200\241` -> 怡
@@ -175,7 +176,8 @@ func Nl2Br(str string, isXhtml ...bool) string {
}
// WordWrap wraps a string to a given number of characters.
-// TODO: Enable cut parameter, see http://php.net/manual/en/function.wordwrap.php.
+// This function supports cut parameters of both english and chinese punctuations.
+// TODO: Enable custom cut parameter, see http://php.net/manual/en/function.wordwrap.php.
func WordWrap(str string, width int, br string) string {
if br == "" {
br = "\n"
@@ -185,9 +187,11 @@ func WordWrap(str string, width int, br string) string {
wordBuf, spaceBuf bytes.Buffer
init = make([]byte, 0, len(str))
buf = bytes.NewBuffer(init)
+ strRunes = []rune(str)
)
- for _, char := range []rune(str) {
- if char == '\n' {
+ for _, char := range strRunes {
+ switch {
+ case char == '\n':
if wordBuf.Len() == 0 {
if current+spaceBuf.Len() > width {
current = 0
@@ -205,7 +209,8 @@ func WordWrap(str string, width int, br string) string {
}
buf.WriteRune(char)
current = 0
- } else if unicode.IsSpace(char) {
+
+ case unicode.IsSpace(char):
if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
current += spaceBuf.Len() + wordBuf.Len()
spaceBuf.WriteTo(buf)
@@ -214,7 +219,18 @@ func WordWrap(str string, width int, br string) string {
wordBuf.Reset()
}
spaceBuf.WriteRune(char)
- } else {
+
+ case isPunctuation(char):
+ wordBuf.WriteRune(char)
+ if spaceBuf.Len() == 0 || wordBuf.Len() > 0 {
+ current += spaceBuf.Len() + wordBuf.Len()
+ spaceBuf.WriteTo(buf)
+ spaceBuf.Reset()
+ wordBuf.WriteTo(buf)
+ wordBuf.Reset()
+ }
+
+ default:
wordBuf.WriteRune(char)
if current+spaceBuf.Len()+wordBuf.Len() > width && wordBuf.Len() < width {
buf.WriteString(br)
@@ -234,3 +250,16 @@ func WordWrap(str string, width int, br string) string {
}
return buf.String()
}
+
+func isPunctuation(char int32) bool {
+ switch char {
+ // English Punctuations.
+ case ';', '.', ',', ':', '~':
+ return true
+ // Chinese Punctuations.
+ case ';', ',', '。', ':', '?', '!', '…', '、':
+ return true
+ default:
+ return false
+ }
+}
diff --git a/text/gstr/gstr_z_unit_convert_test.go b/text/gstr/gstr_z_unit_convert_test.go
index 370689b90..4d0a7a813 100644
--- a/text/gstr/gstr_z_unit_convert_test.go
+++ b/text/gstr/gstr_z_unit_convert_test.go
@@ -4,8 +4,6 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
-// go test *.go -bench=".*"
-
package gstr_test
import (
@@ -20,3 +18,25 @@ func Test_OctStr(t *testing.T) {
t.Assert(gstr.OctStr(`\346\200\241`), "怡")
})
}
+
+func Test_WordWrap(t *testing.T) {
+ gtest.C(t, func(t *gtest.T) {
+ t.Assert(gstr.WordWrap("12 34", 2, "
"), "12
34")
+ t.Assert(gstr.WordWrap("12 34", 2, "\n"), "12\n34")
+ t.Assert(gstr.WordWrap("我爱 GF", 2, "\n"), "我爱\nGF")
+ t.Assert(gstr.WordWrap("A very long woooooooooooooooooord. and something", 7, "
"),
+ "A very
long
woooooooooooooooooord.
and
something")
+ })
+ // Chinese Punctuations.
+ gtest.C(t, func(t *gtest.T) {
+ var (
+ br = " "
+ content = " DelRouteKeyIPv6 删除VPC内的服务的Route信息;和DelRouteIPv6接口相比,这个接口可以删除满足条件的多条RS\n"
+ length = 120
+ )
+ wrappedContent := gstr.WordWrap(content, length, "\n"+br)
+ t.Assert(wrappedContent, ` DelRouteKeyIPv6 删除VPC内的服务的Route信息;和DelRouteIPv6接口相比,
+ 这个接口可以删除满足条件的多条RS
+`)
+ })
+}
diff --git a/text/gstr/gstr_z_unit_test.go b/text/gstr/gstr_z_unit_test.go
index 71e020ea9..1afc3a546 100644
--- a/text/gstr/gstr_z_unit_test.go
+++ b/text/gstr/gstr_z_unit_test.go
@@ -213,16 +213,6 @@ func Test_CountChars(t *testing.T) {
})
}
-func Test_WordWrap(t *testing.T) {
- gtest.C(t, func(t *gtest.T) {
- t.Assert(gstr.WordWrap("12 34", 2, "
"), "12
34")
- t.Assert(gstr.WordWrap("12 34", 2, "\n"), "12\n34")
- t.Assert(gstr.WordWrap("我爱 GF", 2, "\n"), "我爱\nGF")
- t.Assert(gstr.WordWrap("A very long woooooooooooooooooord. and something", 7, "
"),
- "A very
long
woooooooooooooooooord.
and
something")
- })
-}
-
func Test_LenRune(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
t.Assert(gstr.LenRune("1234"), 4)