Skip to content

Instantly share code, notes, and snippets.

@ulexxander
Created October 30, 2021 11:07
Show Gist options
  • Save ulexxander/160ab78abbbc6781083a8c93eaecf3d7 to your computer and use it in GitHub Desktop.
Save ulexxander/160ab78abbbc6781083a8c93eaecf3d7 to your computer and use it in GitHub Desktop.
func splitEscaped(s string, sep, esc rune) []string {
var pos int
a := strings.FieldsFunc(s, func(r rune) bool {
escaped := pos > 0 && rune(s[pos-1]) == esc
pos++
return r == sep && !escaped
})
for i, s := range a {
a[i] = strings.ReplaceAll(s, string(esc)+string(sep), string(sep))
}
return a
}
func TestSplitEscaped(t *testing.T) {
tt := []struct {
s string
sep, esc rune
splitted []string
}{
{
s: "",
sep: ',',
esc: '\\',
splitted: []string{},
},
{
s: "1,2,3",
sep: ',',
esc: '\\',
splitted: []string{"1", "2", "3"},
},
{
s: "1,2\\,3",
sep: ',',
esc: '\\',
splitted: []string{"1", "2,3"},
},
}
for _, tc := range tt {
name := fmt.Sprintf("s=%s sep=%s esc=%s", tc.s, string(tc.sep), string(tc.esc))
t.Run(name, func(t *testing.T) {
result := splitEscaped(tc.s, tc.sep, tc.esc)
if !reflect.DeepEqual(result, tc.splitted) {
t.Fatalf("expected %v, got: %v", tc.splitted, result)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment