Skip to content

Commit f76e37b

Browse files
kellrottncw
authored andcommitted
Adding split method to string class
1 parent 61059b4 commit f76e37b

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

py/string.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"fmt"
1818
"strconv"
1919
"strings"
20+
"unicode"
2021
"unicode/utf8"
2122
)
2223

@@ -34,6 +35,73 @@ or repr(object).
3435
encoding defaults to sys.getdefaultencoding().
3536
errors defaults to 'strict'.`, StrNew, nil)
3637

38+
// standard golang strings.Fields doesn't have a 'first N' argument
39+
func fieldsN(s string, n int) []string {
40+
out := []string{}
41+
cur := []rune{}
42+
r := []rune(s)
43+
for _, c := range r {
44+
//until we have covered the first N elements, multiple white-spaces are 'merged'
45+
if n < 0 || len(out) < n {
46+
if unicode.IsSpace(c) {
47+
if len(cur) > 0 {
48+
out = append(out, string(cur))
49+
cur = []rune{}
50+
}
51+
} else {
52+
cur = append(cur, c)
53+
}
54+
//until we see the next letter, after collecting the first N fields, continue to merge whitespaces
55+
} else if len(out) == n && len(cur) == 0 {
56+
if !unicode.IsSpace(c) {
57+
cur = append(cur, c)
58+
}
59+
//now that enough words have been collected, just copy into the last element
60+
} else {
61+
cur = append(cur, c)
62+
}
63+
}
64+
if len(cur) > 0 {
65+
out = append(out, string(cur))
66+
}
67+
return out
68+
}
69+
70+
func init() {
71+
StringType.Dict["split"] = MustNewMethod("split", func(self Object, args Tuple) (Object, error) {
72+
selfStr := self.(String)
73+
var value Object = None
74+
zeroRemove := true
75+
if len(args) > 0 {
76+
if _, ok := args[0].(NoneType); !ok {
77+
value = args[0]
78+
zeroRemove = false
79+
}
80+
}
81+
var maxSplit int = -2
82+
if len(args) > 1 {
83+
if m, ok := args[1].(Int); ok {
84+
maxSplit = int(m)
85+
}
86+
}
87+
valArray := []string{}
88+
if valStr, ok := value.(String); ok {
89+
valArray = strings.SplitN(string(selfStr), string(valStr), maxSplit+1)
90+
} else if _, ok := value.(NoneType); ok {
91+
valArray = fieldsN(string(selfStr), maxSplit)
92+
} else {
93+
return nil, ExceptionNewf(TypeError, "Can't convert '%s' object to str implicitly", value.Type())
94+
}
95+
o := List{}
96+
for _, j := range valArray {
97+
if len(j) > 0 || !zeroRemove {
98+
o.Items = append(o.Items, String(j))
99+
}
100+
}
101+
return &o, nil
102+
}, 0, "split(sub) -> split string with sub.")
103+
}
104+
37105
// Type of this object
38106
func (s String) Type() *Type {
39107
return StringType

py/tests/string.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,14 @@ class C():
9999
asc="hello"
100100
uni="£100世界𠜎" # 1,2,3,4 byte unicode characters
101101

102+
doc="split"
103+
assert ["0","1","2","4"] == list("0,1,2,4".split(","))
104+
assert [""] == list("".split(","))
105+
assert ['a', 'd,c'] == list("a,d,c".split(",",1))
106+
assert ['a', 'd', 'b'] == list(" a d b ".split())
107+
assert ['a', 'd b '] == list(" a d b ".split(None, 1))
108+
assertRaisesText(TypeError, "Can't convert 'int' object to str implicitly", lambda: "0,1,2,4".split(1))
109+
102110
doc="ascii len"
103111
assert len(asc) == 5
104112

0 commit comments

Comments
 (0)