builtin: cleanup string trim()/trim_left()/trim_right() (#22225)

This commit is contained in:
yuyi 2024-09-16 01:05:42 +08:00 committed by GitHub
parent 9b88dc8deb
commit ca5f47a966
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 54 deletions

View File

@ -1721,9 +1721,9 @@ pub fn (s string) trim(cutset string) string {
return s.clone() return s.clone()
} }
if cutset.len_utf8() == cutset.len { if cutset.len_utf8() == cutset.len {
return s.trim_chars(cutset) return s.trim_chars(cutset, .trim_both)
} else { } else {
return s.trim_runes(cutset) return s.trim_runes(cutset, .trim_both)
} }
} }
@ -1757,25 +1757,35 @@ pub fn (s string) trim_indexes(cutset string) (int, int) {
return pos_left, pos_right + 1 return pos_left, pos_right + 1
} }
enum TrimMode {
trim_left
trim_right
trim_both
}
@[direct_array_access] @[direct_array_access]
fn (s string) trim_chars(cutset string) string { fn (s string) trim_chars(cutset string, mode TrimMode) string {
mut pos_left := 0 mut pos_left := 0
mut pos_right := s.len - 1 mut pos_right := s.len - 1
mut cs_match := true mut cs_match := true
for pos_left <= s.len && pos_right >= -1 && cs_match { for pos_left <= s.len && pos_right >= -1 && cs_match {
cs_match = false cs_match = false
for cs in cutset { if mode in [.trim_left, .trim_both] {
if s[pos_left] == cs { for cs in cutset {
pos_left++ if s[pos_left] == cs {
cs_match = true pos_left++
break cs_match = true
break
}
} }
} }
for cs in cutset { if mode in [.trim_right, .trim_both] {
if s[pos_right] == cs { for cs in cutset {
pos_right-- if s[pos_right] == cs {
cs_match = true pos_right--
break cs_match = true
break
}
} }
} }
if pos_left > pos_right { if pos_left > pos_right {
@ -1786,7 +1796,7 @@ fn (s string) trim_chars(cutset string) string {
} }
@[direct_array_access] @[direct_array_access]
fn (s string) trim_runes(cutset string) string { fn (s string) trim_runes(cutset string, mode TrimMode) string {
s_runes := s.runes() s_runes := s.runes()
c_runes := cutset.runes() c_runes := cutset.runes()
mut pos_left := 0 mut pos_left := 0
@ -1794,18 +1804,22 @@ fn (s string) trim_runes(cutset string) string {
mut cs_match := true mut cs_match := true
for pos_left <= s_runes.len && pos_right >= -1 && cs_match { for pos_left <= s_runes.len && pos_right >= -1 && cs_match {
cs_match = false cs_match = false
for cs in c_runes { if mode in [.trim_left, .trim_both] {
if s_runes[pos_left] == cs { for cs in c_runes {
pos_left++ if s_runes[pos_left] == cs {
cs_match = true pos_left++
break cs_match = true
break
}
} }
} }
for cs in c_runes { if mode in [.trim_right, .trim_both] {
if s_runes[pos_right] == cs { for cs in c_runes {
pos_right-- if s_runes[pos_right] == cs {
cs_match = true pos_right--
break cs_match = true
break
}
} }
} }
if pos_left > pos_right { if pos_left > pos_right {
@ -1822,21 +1836,11 @@ pub fn (s string) trim_left(cutset string) string {
if s == '' || cutset == '' { if s == '' || cutset == '' {
return s.clone() return s.clone()
} }
mut pos := 0 if cutset.len_utf8() == cutset.len {
for pos < s.len { return s.trim_chars(cutset, .trim_left)
mut found := false } else {
for cs in cutset { return s.trim_runes(cutset, .trim_left)
if s[pos] == cs {
found = true
break
}
}
if !found {
break
}
pos++
} }
return s[pos..]
} }
// trim_right strips any of the characters given in `cutset` from the right of the string. // trim_right strips any of the characters given in `cutset` from the right of the string.
@ -1846,23 +1850,11 @@ pub fn (s string) trim_right(cutset string) string {
if s.len < 1 || cutset.len < 1 { if s.len < 1 || cutset.len < 1 {
return s.clone() return s.clone()
} }
mut pos := s.len - 1 if cutset.len_utf8() == cutset.len {
for pos >= 0 { return s.trim_chars(cutset, .trim_right)
mut found := false } else {
for cs in cutset { return s.trim_runes(cutset, .trim_right)
if s[pos] == cs {
found = true
}
}
if !found {
break
}
pos--
} }
if pos < 0 {
return ''
}
return s[..pos + 1]
} }
// trim_string_left strips `str` from the start of the string. // trim_string_left strips `str` from the start of the string.

View File

@ -943,6 +943,7 @@ fn test_trim_left() {
s = 'banana' s = 'banana'
assert s.trim_left('ba') == 'nana' assert s.trim_left('ba') == 'nana'
assert s.trim_left('ban') == '' assert s.trim_left('ban') == ''
assert ''.trim_left('') == ''
} }
fn test_trim_right() { fn test_trim_right() {
@ -954,6 +955,7 @@ fn test_trim_right() {
s = 'banana' s = 'banana'
assert s.trim_right('na') == 'b' assert s.trim_right('na') == 'b'
assert s.trim_right('ban') == '' assert s.trim_right('ban') == ''
assert ''.trim_right('') == ''
} }
fn test_all_before() { fn test_all_before() {