Add util.SubstringByRune

This commit is contained in:
Cheer Xiao 2014-09-21 13:20:33 +02:00
parent 37a8fb263e
commit a4cfc41673
2 changed files with 59 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package util
import (
"errors"
"strings"
)
@ -36,3 +37,35 @@ func FindFirstEOL(s string) int {
func FindLastSOL(s string) int {
return strings.LastIndex(s, "\n") + 1
}
var (
IndexOutOfRange = errors.New("substring out of range")
)
// SubStringByRune returns the range of the i-th rune (inclusive) through the
// j-th rune (exclusive) in s.
func SubstringByRune(s string, low, high int) (string, error) {
if low > high || low < 0 || high < 0 {
return "", IndexOutOfRange
}
var bLow, bHigh, j int
for i := range s {
if j == low {
bLow = i
}
if j == high {
bHigh = i
}
j++
}
if j < high {
return "", IndexOutOfRange
}
if low == high {
return "", nil
}
if j == high {
bHigh = len(s)
}
return s[bLow:bHigh], nil
}

View File

@ -20,3 +20,29 @@ func TestFindContext(t *testing.T) {
}
}
}
var SubstringByRuneTests = []struct {
s string
low, high int
wantedStr string
wantedErr error
}{
{"Hello world", 1, 4, "ell", nil},
{"你好世界", 0, 0, "", nil},
{"你好世界", 1, 1, "", nil},
{"你好世界", 1, 2, "好", nil},
{"你好世界", 1, 4, "好世界", nil},
{"你好世界", -1, -1, "", IndexOutOfRange},
{"你好世界", 0, 5, "", IndexOutOfRange},
{"你好世界", 5, 5, "", IndexOutOfRange},
}
func TestSubstringByRune(t *testing.T) {
for _, tt := range SubstringByRuneTests {
s, e := SubstringByRune(tt.s, tt.low, tt.high)
if s != tt.wantedStr || e != tt.wantedErr {
t.Errorf("SubstringByRune(%q, %v, %d) => (%q, %v), want (%q, %v)",
tt.s, tt.low, tt.high, s, e, tt.wantedStr, tt.wantedErr)
}
}
}