Skip to content

Commit 14d2d74

Browse files
authored
add minus of start parameter support for gstr.Substr, like the substr function in PHP (#2297)
* Make the substr like the substr in PHP Make the substr like the substr in PHP * Update gstr_z_unit_test.go * Update gstr_z_unit_test.go * Make the SubStrRune like the mb_substr in PHP Make the SubStrRune like the mb_substr in PHP * Update gstr_z_unit_test.go * Update gstr_z_unit_test.go * Update gins_z_unit_view_test.go * Update gview_z_unit_test.go
1 parent 73dc8c9 commit 14d2d74

File tree

4 files changed

+64
-27
lines changed

4 files changed

+64
-27
lines changed

frame/gins/gins_z_unit_view_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func Test_View(t *testing.T) {
2222
t.AssertNE(View(), nil)
2323
b, e := View().ParseContent(context.TODO(), `{{"我是中国人" | substr 2 -1}}`, nil)
2424
t.Assert(e, nil)
25-
t.Assert(b, "中国人")
25+
t.Assert(b, "中国")
2626
})
2727
gtest.C(t, func(t *gtest.T) {
2828
tpl := "t.tpl"
@@ -32,7 +32,7 @@ func Test_View(t *testing.T) {
3232

3333
b, e := View().Parse(context.TODO(), "t.tpl", nil)
3434
t.Assert(e, nil)
35-
t.Assert(b, "中国人")
35+
t.Assert(b, "中国")
3636
})
3737
gtest.C(t, func(t *gtest.T) {
3838
path := fmt.Sprintf(`%s/%d`, gfile.Temp(), gtime.TimestampNano())
@@ -45,7 +45,7 @@ func Test_View(t *testing.T) {
4545

4646
b, e := View().Parse(context.TODO(), "t.tpl", nil)
4747
t.Assert(e, nil)
48-
t.Assert(b, "中国人")
48+
t.Assert(b, "中国")
4949
})
5050
}
5151

os/gview/gview_z_unit_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func Test_Func(t *testing.T) {
141141
str = `{{"我是中国人" | substr 2 -1}};{{"我是中国人" | substr 2 2}}`
142142
result, err = gview.ParseContent(context.TODO(), str, nil)
143143
t.Assert(err != nil, false)
144-
t.Assert(result, `中国人;中国`)
144+
t.Assert(result, `中国;中国`)
145145

146146
str = `{{"我是中国人" | strlimit 2 "..."}}`
147147
result, err = gview.ParseContent(context.TODO(), str, nil)

text/gstr/gstr_sub.go

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,24 +55,37 @@ func StrTillEx(haystack string, needle string) string {
5555
// The parameter `length` is optional, it uses the length of `str` in default.
5656
func SubStr(str string, start int, length ...int) (substr string) {
5757
strLength := len(str)
58-
// Simple border checks.
5958
if start < 0 {
60-
start = 0
61-
}
62-
if start >= strLength {
63-
start = strLength
59+
if -start > strLength {
60+
start = 0
61+
} else {
62+
start = strLength + start
63+
}
64+
} else if start > strLength {
65+
return ""
6466
}
65-
end := strLength
67+
realLength := 0
6668
if len(length) > 0 {
67-
end = start + length[0]
68-
if end < start {
69-
end = strLength
69+
realLength = length[0]
70+
if realLength < 0 {
71+
if -realLength > strLength-start {
72+
realLength = 0
73+
} else {
74+
realLength = strLength - start + realLength
75+
}
76+
} else if realLength > strLength-start {
77+
realLength = strLength - start
7078
}
79+
} else {
80+
realLength = strLength - start
7181
}
72-
if end > strLength {
73-
end = strLength
82+
83+
if realLength == strLength {
84+
return str
85+
} else {
86+
end := start + realLength
87+
return str[start:end]
7488
}
75-
return str[start:end]
7689
}
7790

7891
// SubStrRune returns a portion of string `str` specified by the `start` and `length` parameters.
@@ -85,20 +98,32 @@ func SubStrRune(str string, start int, length ...int) (substr string) {
8598
runesLength = len(runes)
8699
)
87100

88-
// Simple border checks.
101+
strLength := runesLength
89102
if start < 0 {
90-
start = 0
91-
}
92-
if start >= runesLength {
93-
start = runesLength
103+
if -start > strLength {
104+
start = 0
105+
} else {
106+
start = strLength + start
107+
}
108+
} else if start > strLength {
109+
return ""
94110
}
95-
end := runesLength
111+
realLength := 0
96112
if len(length) > 0 {
97-
end = start + length[0]
98-
if end < start {
99-
end = runesLength
113+
realLength = length[0]
114+
if realLength < 0 {
115+
if -realLength > strLength-start {
116+
realLength = 0
117+
} else {
118+
realLength = strLength - start + realLength
119+
}
120+
} else if realLength > strLength-start {
121+
realLength = strLength - start
100122
}
123+
} else {
124+
realLength = strLength - start
101125
}
126+
end := start + realLength
102127
if end > runesLength {
103128
end = runesLength
104129
}

text/gstr/gstr_z_unit_test.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,12 @@ func Test_SubStr(t *testing.T) {
8989
t.Assert(gstr.SubStr("我爱GoFrame", 0), "我爱GoFrame")
9090
t.Assert(gstr.SubStr("我爱GoFrame", 6), "GoFrame")
9191
t.Assert(gstr.SubStr("我爱GoFrame", 6, 2), "Go")
92-
t.Assert(gstr.SubStr("我爱GoFrame", -1, 30), "我爱GoFrame")
92+
t.Assert(gstr.SubStr("我爱GoFrame", -1, 30), "e")
9393
t.Assert(gstr.SubStr("我爱GoFrame", 30, 30), "")
94+
t.Assert(gstr.SubStr("abcdef", 0, -1), "abcde")
95+
t.Assert(gstr.SubStr("abcdef", 2, -1), "cde")
96+
t.Assert(gstr.SubStr("abcdef", 4, -4), "")
97+
t.Assert(gstr.SubStr("abcdef", -3, -1), "de")
9498
})
9599
}
96100

@@ -99,8 +103,16 @@ func Test_SubStrRune(t *testing.T) {
99103
t.Assert(gstr.SubStrRune("我爱GoFrame", 0), "我爱GoFrame")
100104
t.Assert(gstr.SubStrRune("我爱GoFrame", 2), "GoFrame")
101105
t.Assert(gstr.SubStrRune("我爱GoFrame", 2, 2), "Go")
102-
t.Assert(gstr.SubStrRune("我爱GoFrame", -1, 30), "我爱GoFrame")
106+
t.Assert(gstr.SubStrRune("我爱GoFrame", -1, 30), "e")
103107
t.Assert(gstr.SubStrRune("我爱GoFrame", 30, 30), "")
108+
t.Assert(gstr.SubStrRune("abcdef", 0, -1), "abcde")
109+
t.Assert(gstr.SubStrRune("abcdef", 2, -1), "cde")
110+
t.Assert(gstr.SubStrRune("abcdef", 4, -4), "")
111+
t.Assert(gstr.SubStrRune("abcdef", -3, -1), "de")
112+
t.Assert(gstr.SubStrRune("我爱GoFrame呵呵", -3, 100), "e呵呵")
113+
t.Assert(gstr.SubStrRune("abcdef哈哈", -3, -1), "f哈")
114+
t.Assert(gstr.SubStrRune("ab我爱GoFramecdef哈哈", -3, -1), "f哈")
115+
t.Assert(gstr.SubStrRune("我爱GoFrame", 0, 3), "我爱G")
104116
})
105117
}
106118

0 commit comments

Comments
 (0)