package strutil

import (
	
	
)

// BeforeFirst get substring before first sep.
func (,  string) string {
	if  := strings.Index(, );  >= 0 {
		return [:]
	}
	return 
}

// AfterFirst get substring after first sep.
func (,  string) string {
	if  := strings.Index(, );  >= 0 {
		return [+len():]
	}
	return ""
}

// BeforeLast get substring before last sep.
func (,  string) string {
	if  := strings.LastIndex(, );  >= 0 {
		return [:]
	}
	return 
}

// AfterLast get substring after last sep.
func (,  string) string {
	if  := strings.LastIndex(, );  >= 0 {
		return [+len():]
	}
	return ""
}

/*************************************************************
 * String split operation
 *************************************************************/

// Cut alias of the strings.Cut
func (,  string) ( string,  string,  bool) {
	if  := strings.Index(, );  >= 0 {
		return [:], [+len():], true
	}
	return , "", false
}

// QuietCut always returns two substring.
func (,  string) ( string,  string) {
	, , _ = Cut(, )
	return
}

// MustCut always returns two substring.
func (,  string) ( string,  string) {
	var  bool
	, ,  = Cut(, )
	if ! {
		panic("cannot split input string to two nodes")
	}
	return
}

// TrimCut always returns two substring and trim space for items.
func (,  string) (string, string) {
	, ,  := Cut(, )
	return strings.TrimSpace(), strings.TrimSpace()
}

// SplitKV split string to key and value.
func (,  string) (string, string) { return TrimCut(, ) }

// SplitValid string to slice. will trim each item and filter empty string node.
func (,  string) ( []string) { return Split(, ) }

// Split string to slice. will trim each item and filter empty string node.
func (,  string) ( []string) {
	if  = strings.TrimSpace();  == "" {
		return
	}

	for ,  := range strings.Split(, ) {
		if  = strings.TrimSpace();  != "" {
			 = append(, )
		}
	}
	return
}

// SplitNValid string to slice. will filter empty string node.
func (,  string,  int) ( []string) { return SplitN(, , ) }

// SplitN string to slice. will filter empty string node.
func (,  string,  int) ( []string) {
	if  = strings.TrimSpace();  == "" {
		return
	}

	 := strings.Split(, )
	for ,  := range  {
		if  = strings.TrimSpace();  != "" {
			if len() == -1 {
				 = append(, strings.TrimSpace(strings.Join([:], )))
				break
			}

			 = append(, )
		}
	}
	return
}

// SplitTrimmed split string to slice.
// will trim space for each node, but not filter empty
func (,  string) ( []string) {
	if  = strings.TrimSpace();  == "" {
		return
	}

	for ,  := range strings.Split(, ) {
		 = append(, strings.TrimSpace())
	}
	return
}

// SplitNTrimmed split string to slice.
// will trim space for each node, but not filter empty
func (,  string,  int) ( []string) {
	if  = strings.TrimSpace();  == "" {
		return
	}

	for ,  := range strings.SplitN(, , ) {
		 = append(, strings.TrimSpace())
	}
	return
}

// 根据空白字符(空格,TAB,换行等)分隔字符串
var whitespaceRegexp = regexp.MustCompile(`\s+`)

// SplitByWhitespace Separate strings by whitespace characters (space, TAB, newline, etc.)
func ( string) []string {
	return whitespaceRegexp.Split(, -1)
}

// Substr for a string. NOTE: strLn := len(runes)
// if length <= 0, return pos to end.
func ( string, ,  int) string {
	 := []rune()
	 := len()

	// pos is too large
	if  >=  {
		return ""
	}

	 :=  + 
	if  == 0 ||  >  {
		 = 
	} else if  < 0 {
		 =  + 
	}

	return string([:])
}

// SplitInlineComment for an inline text string. default is strict mode.
func ( string,  ...bool) (string, string) {
	// strict check: must with a space
	if len() == 0 || [0] {
		if  := strings.Index(, " #");  > -1 {
			return strings.TrimRight([0:], " "), [+1:]
		}
		if  := strings.Index(, " //");  > -1 {
			return strings.TrimRight([0:], " "), [+1:]
		}
		return , ""
	}

	if  := strings.IndexByte(, '#');  > -1 {
		return strings.TrimRight([0:], " "), [:]
	}
	if  := strings.Index(, "//");  > -1 {
		return strings.TrimRight([0:], " "), [:]
	}
	return , ""
}

// FirstLine from command output
func ( string) string {
	if  := strings.IndexByte(, '\n');  >= 0 {
		return [0:]
	}
	return 
}