Skip to content

Commit

Permalink
builtin: fix string.trim()
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Sep 12, 2024
1 parent e0422de commit d6ce544
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
45 changes: 38 additions & 7 deletions vlib/builtin/string.v
Original file line number Diff line number Diff line change
Expand Up @@ -1720,14 +1720,15 @@ pub fn (s string) trim(cutset string) string {
if s == '' || cutset == '' {
return s.clone()
}
left, right := s.trim_indexes(cutset)
return s.substr(left, right)
if cutset.len_utf8() == cutset.len {
return s.trim_chars(cutset)
} else {
return s.trim_runes(cutset)
}
}

// trim_indexes gets the new start and end indices of a string when any of the characters given in `cutset` were stripped from the start and end of the string. Should be used as an input to `substr()`. If the string contains only the characters in `cutset`, both values returned are zero.
// Example: left, right := '-hi-'.trim_indexes('-')
@[direct_array_access]
pub fn (s string) trim_indexes(cutset string) (int, int) {
pub fn (s string) trim_chars(cutset string) string {
mut pos_left := 0
mut pos_right := s.len - 1
mut cs_match := true
Expand All @@ -1748,10 +1749,40 @@ pub fn (s string) trim_indexes(cutset string) (int, int) {
}
}
if pos_left > pos_right {
return 0, 0
return ''
}
}
return s.substr(pos_left, pos_right + 1)
}

@[direct_array_access]
pub fn (s string) trim_runes(cutset string) string {
s_runes := s.runes()
c_runes := cutset.runes()
mut pos_left := 0
mut pos_right := s_runes.len - 1
mut cs_match := true
for pos_left <= s_runes.len && pos_right >= -1 && cs_match {
cs_match = false
for cs in c_runes {
if s_runes[pos_left] == cs {
pos_left++
cs_match = true
break
}
}
for cs in c_runes {
if s_runes[pos_right] == cs {
pos_right--
cs_match = true
break
}
}
if pos_left > pos_right {
return ''
}
}
return pos_left, pos_right + 1
return s_runes[pos_left..pos_right + 1].string()
}

// trim_left strips any of the characters given in `cutset` from the left of the string.
Expand Down
11 changes: 1 addition & 10 deletions vlib/builtin/string_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -921,16 +921,7 @@ fn test_trim() {
assert 'banana'.trim('bna') == ''
assert 'abc'.trim('ac') == 'b'
assert 'aaabccc'.trim('ac') == 'b'
}

fn test_trim_indexes() {
mut left, mut right := 0, 0
left, right = '- -- - '.trim_indexes(' -')
assert left == 0 && right == 0
left, right = '- hello-world!\t'.trim_indexes(' -\t')
assert left == 2 && right == 14
left, right = 'abc'.trim_indexes('ac')
assert left == 1 && right == 2
assert 'あいうえお'.trim('あい') == 'うえお'
}

fn test_trim_left() {
Expand Down

0 comments on commit d6ce544

Please sign in to comment.