lab.nexedi.com/kirr/go123@v0.0.0-20240207185015-8299741fa871/xstrings/xstrings.go (about) 1 // Copyright (C) 2015-2019 Nexedi SA and Contributors. 2 // Kirill Smelkov <kirr@nexedi.com> 3 // 4 // This program is free software: you can Use, Study, Modify and Redistribute 5 // it under the terms of the GNU General Public License version 3, or (at your 6 // option) any later version, as published by the Free Software Foundation. 7 // 8 // You can also Link and Combine this program with other software covered by 9 // the terms of any of the Free Software licenses or any of the Open Source 10 // Initiative approved licenses and Convey the resulting work. Corresponding 11 // source of such a combination shall include the source code for all other 12 // software used. 13 // 14 // This program is distributed WITHOUT ANY WARRANTY; without even the implied 15 // warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 // 17 // See COPYING file for full licensing terms. 18 // See https://www.nexedi.com/licensing for rationale and options. 19 20 // Package xstrings provides addons to standard package strings. 21 package xstrings 22 23 import ( 24 "fmt" 25 "strings" 26 ) 27 28 // SplitLines splits string into lines. 29 // 30 // The last line, if it is empty, is omitted from the result. 31 // (rationale is: string.Split("hello\nworld\n", "\n") -> ["hello", "world", ""]) 32 func SplitLines(s, sep string) []string { 33 sv := strings.Split(s, sep) 34 l := len(sv) 35 if l > 0 && sv[l-1] == "" { 36 sv = sv[:l-1] 37 } 38 return sv 39 } 40 41 // Split2 splits string by sep and expects exactly 2 parts. 42 func Split2(s, sep string) (s1, s2 string, err error) { 43 parts := strings.Split(s, sep) 44 if len(parts) != 2 { 45 return "", "", fmt.Errorf("split2: %q has %v parts (expected 2, sep: %q)", s, len(parts), sep) 46 } 47 return parts[0], parts[1], nil 48 } 49 50 // HeadTail splits string into head & tail. 51 // 52 // (head+sep+tail) -> head, tail. 53 // 54 // Note: tail may contain sep. 55 func HeadTail(s, sep string) (head, tail string, err error) { 56 parts := strings.SplitN(s, sep, 2) 57 if len(parts) != 2 { 58 return "", "", fmt.Errorf("headtail: %q has no %q", s, sep) 59 } 60 return parts[0], parts[1], nil 61 }