mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-05-02 13:13:34 -04:00
The goutil that OpenCloud currently uses is one version from the release that adds FreeBSD support, this now compiles successfully on FreeBSD.
201 lines
4.8 KiB
Go
201 lines
4.8 KiB
Go
package strutil
|
||
|
||
import (
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
// BeforeFirst get substring before first sep.
|
||
func BeforeFirst(s, sep string) string {
|
||
if i := strings.Index(s, sep); i >= 0 {
|
||
return s[:i]
|
||
}
|
||
return s
|
||
}
|
||
|
||
// AfterFirst get substring after first sep.
|
||
func AfterFirst(s, sep string) string {
|
||
if i := strings.Index(s, sep); i >= 0 {
|
||
return s[i+len(sep):]
|
||
}
|
||
return ""
|
||
}
|
||
|
||
// BeforeLast get substring before last sep.
|
||
func BeforeLast(s, sep string) string {
|
||
if i := strings.LastIndex(s, sep); i >= 0 {
|
||
return s[:i]
|
||
}
|
||
return s
|
||
}
|
||
|
||
// AfterLast get substring after last sep.
|
||
func AfterLast(s, sep string) string {
|
||
if i := strings.LastIndex(s, sep); i >= 0 {
|
||
return s[i+len(sep):]
|
||
}
|
||
return ""
|
||
}
|
||
|
||
/*************************************************************
|
||
* String split operation
|
||
*************************************************************/
|
||
|
||
// Cut alias of the strings.Cut
|
||
func Cut(s, sep string) (before string, after string, found bool) {
|
||
if i := strings.Index(s, sep); i >= 0 {
|
||
return s[:i], s[i+len(sep):], true
|
||
}
|
||
return s, "", false
|
||
}
|
||
|
||
// QuietCut always returns two substring.
|
||
func QuietCut(s, sep string) (before string, after string) {
|
||
before, after, _ = Cut(s, sep)
|
||
return
|
||
}
|
||
|
||
// MustCut always returns two substring.
|
||
func MustCut(s, sep string) (before string, after string) {
|
||
var ok bool
|
||
before, after, ok = Cut(s, sep)
|
||
if !ok {
|
||
panic("cannot split input string to two nodes")
|
||
}
|
||
return
|
||
}
|
||
|
||
// TrimCut always returns two substring and trim space for items.
|
||
func TrimCut(s, sep string) (string, string) {
|
||
before, after, _ := Cut(s, sep)
|
||
return strings.TrimSpace(before), strings.TrimSpace(after)
|
||
}
|
||
|
||
// SplitKV split string to key and value.
|
||
func SplitKV(s, sep string) (string, string) { return TrimCut(s, sep) }
|
||
|
||
// SplitValid string to slice. will trim each item and filter empty string node.
|
||
func SplitValid(s, sep string) (ss []string) { return Split(s, sep) }
|
||
|
||
// Split string to slice. will trim each item and filter empty string node.
|
||
func Split(s, sep string) (ss []string) {
|
||
if s = strings.TrimSpace(s); s == "" {
|
||
return
|
||
}
|
||
|
||
for _, val := range strings.Split(s, sep) {
|
||
if val = strings.TrimSpace(val); val != "" {
|
||
ss = append(ss, val)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// SplitNValid string to slice. will filter empty string node.
|
||
func SplitNValid(s, sep string, n int) (ss []string) { return SplitN(s, sep, n) }
|
||
|
||
// SplitN string to slice. will filter empty string node.
|
||
func SplitN(s, sep string, n int) (ss []string) {
|
||
if s = strings.TrimSpace(s); s == "" {
|
||
return
|
||
}
|
||
|
||
rawList := strings.Split(s, sep)
|
||
for i, val := range rawList {
|
||
if val = strings.TrimSpace(val); val != "" {
|
||
if len(ss) == n-1 {
|
||
ss = append(ss, strings.TrimSpace(strings.Join(rawList[i:], sep)))
|
||
break
|
||
}
|
||
|
||
ss = append(ss, val)
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// SplitTrimmed split string to slice.
|
||
// will trim space for each node, but not filter empty
|
||
func SplitTrimmed(s, sep string) (ss []string) {
|
||
if s = strings.TrimSpace(s); s == "" {
|
||
return
|
||
}
|
||
|
||
for _, val := range strings.Split(s, sep) {
|
||
ss = append(ss, strings.TrimSpace(val))
|
||
}
|
||
return
|
||
}
|
||
|
||
// SplitNTrimmed split string to slice.
|
||
// will trim space for each node, but not filter empty
|
||
func SplitNTrimmed(s, sep string, n int) (ss []string) {
|
||
if s = strings.TrimSpace(s); s == "" {
|
||
return
|
||
}
|
||
|
||
for _, val := range strings.SplitN(s, sep, n) {
|
||
ss = append(ss, strings.TrimSpace(val))
|
||
}
|
||
return
|
||
}
|
||
|
||
// 根据空白字符(空格,TAB,换行等)分隔字符串
|
||
var whitespaceRegexp = regexp.MustCompile("\\s+")
|
||
|
||
// SplitByWhitespace Separate strings by whitespace characters (space, TAB, newline, etc.)
|
||
func SplitByWhitespace(s string) []string {
|
||
return whitespaceRegexp.Split(s, -1)
|
||
}
|
||
|
||
// Substr for a string. NOTE: strLn := len(runes)
|
||
// if length <= 0, return pos to end.
|
||
func Substr(s string, pos, length int) string {
|
||
runes := []rune(s)
|
||
strLn := len(runes)
|
||
|
||
// pos is too large
|
||
if pos >= strLn {
|
||
return ""
|
||
}
|
||
|
||
stopIdx := pos + length
|
||
if length == 0 || stopIdx > strLn {
|
||
stopIdx = strLn
|
||
} else if length < 0 {
|
||
stopIdx = strLn + length
|
||
}
|
||
|
||
return string(runes[pos:stopIdx])
|
||
}
|
||
|
||
// SplitInlineComment for an inline text string. default is strict mode.
|
||
func SplitInlineComment(val string, strict ...bool) (string, string) {
|
||
// strict check: must with a space
|
||
if len(strict) == 0 || strict[0] {
|
||
if pos := strings.Index(val, " #"); pos > -1 {
|
||
return strings.TrimRight(val[0:pos], " "), val[pos+1:]
|
||
}
|
||
if pos := strings.Index(val, " //"); pos > -1 {
|
||
return strings.TrimRight(val[0:pos], " "), val[pos+1:]
|
||
}
|
||
return val, ""
|
||
}
|
||
|
||
if pos := strings.IndexByte(val, '#'); pos > -1 {
|
||
return strings.TrimRight(val[0:pos], " "), val[pos:]
|
||
}
|
||
if pos := strings.Index(val, "//"); pos > -1 {
|
||
return strings.TrimRight(val[0:pos], " "), val[pos:]
|
||
}
|
||
return val, ""
|
||
}
|
||
|
||
// FirstLine from command output
|
||
func FirstLine(output string) string {
|
||
if i := strings.IndexByte(output, '\n'); i >= 0 {
|
||
return output[0:i]
|
||
}
|
||
return output
|
||
}
|