// Golang regexp module does not support /(?!\\),/ syntax for spliting by not escaped comma
// Then this function is reproducing it
976748
func recParseEscapedComma(str string) []string {
	if len(str) == 0 {
		return []string{}
	} else if str[0] == ',' {
		return recParseEscapedComma(str[1:])
	}

	offset := 0
	for len(str[offset:]) > 0 {
		index := strings.Index(str[offset:], ",")

		if index == -1 {
			break
		} else if str[offset+index-1:offset+index] != "\\" {
			return append(recParseEscapedComma(str[offset+index+1:]), str[:offset+index])
		}

		str = str[:offset+index-1] + str[offset+index:]
		offset += index
	}

	return []string{str}
}
735041
func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
	if h, ok := t.(tHelper); ok {
		h.Helper()
	}
	return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
}
808117
func string_splitlines(fnname string, recv Value, args Tuple, kwargs []Tuple) (Value, error) {
	var keepends bool
	if err := UnpackPositionalArgs(fnname, args, kwargs, 0, &keepends); err != nil {
		return nil, err
	}
	s := string(recv.(String))
	var lines []string
	// TODO(adonovan): handle CRLF correctly.
	if keepends {
		lines = strings.SplitAfter(s, "\n")
	} else {
		lines = strings.Split(s, "\n")
	}
	if strings.HasSuffix(s, "\n") {
		lines = lines[:len(lines)-1]
	}
	list := make([]Value, len(lines))
	for i, x := range lines {
		list[i] = String(x)
	}
	return NewList(list), nil
}
857193
func getRegEx(pattern string) *regexp.Regexp {
	for _, trs := range []struct {
		old, new string
	}{
		{".", `\.`}, // Escape all '.' in the pattern
		{"(", `\(`}, // Escape all '(' in the pattern
		{")", `\)`}, // Escape all ')' in the pattern
		{"*", ".*"}, // Replace a '*' with '.*' that matches zero or more chars
		{"{", "("},  // Change a '{' to '('
		{",", "|"},  // Change a ',' to '|'
		{"}", ")"},  // Change a '}' to ')'
		{"?", "."},  // Change a '?' to '.'
	} {
		pattern = strings.Replace(pattern, trs.old, trs.new, -1)
	}

	return regexp.MustCompile(pattern)
}
726565
func ReplaceAll(rgx *regexp.Regexp, src *[]byte, rpl []byte) {
	// Find all matches
	var start, end, delta, offset, i int
	var l = len(rpl)
	for _, indexes := range rgx.FindAllIndex(*src, -1) {
		// Update indexes
		start = indexes[0] + offset
		end = indexes[1] + offset
		delta = (end - start) - l
		offset -= delta

		// Update src length
		if delta < 0 {
			// Insert
			(*src) = append((*src)[:start], append(make([]byte, -delta), (*src)[start:]...)...)
		} else if delta > 0 {
			// Delete
			(*src) = append((*src)[:start], (*src)[start+delta:]...)
		}

		// Update src content
		for i = 0; i < l; i++ {
			(*src)[i+start] = rpl[i]
		}
	}
}
649340
func MustCompilePOSIX(str string) *regexp.Regexp {
	re, err := posixContainer.Get(str)
	if err != nil {
		// regexp.MustCompilePOSIX() like message
		panic(`regexpcache: CompilePOSIX(` + quote(str) + `): ` + err.Error())
	}
	return re
}
499360
func RegexError(msg string, fmt string, examples ...string) string {
	if len(examples) == 0 {
		return msg + " (regex used for validation is '" + fmt + "')"
	}
	msg += " (e.g. "
	for i := range examples {
		if i > 0 {
			msg += " or "
		}
		msg += "'" + examples[i] + "', "
	}
	msg += "regex used for validation is '" + fmt + "')"
	return msg
}
1051059
func (bot *TgBot) RegexFn(path string, f func(TgBot, Message, []string, map[string]string) *string) *TgBot {
	r := regexp.MustCompile(path)

	bot.addToConditionalFuncs(TextConditionalCall{RegexCommand{r, f}})
	return bot
}
1329332
func (l *Lexer) findRegexp(r *regexp.Regexp) string {
	return r.FindString(l.input[l.pos:])
}
281646
func PrintMatchers(all []string) {
	sort.Strings(all)
	var element string

	fmt.Println("package tokeq")
	fmt.Println("\nimport (\n\t\"golang.org/x/net/html\"\n\t\"golang.org/x/net/html/atom\"\n)")
	fmt.Println("")
	fmt.Println("// https://raw.githubusercontent.com/golang/net/master/html/atom/gen.go")
	fmt.Println("// generated by go run gen.go; DO NOT EDIT")
	fmt.Println("")
	fmt.Println("")

	for _, s := range all {
		element = identifier(s)
		fmt.Printf("func Match%s(t html.NodeType, a atom.Atom) bool {\n\treturn a == atom.%s\n}\n\n", element, element)
	}
	os.Exit(1)
}
259268
func ValidateRegexp(v interface{}, k string) (ws []string, errors []error) {
	if _, err := regexp.Compile(v.(string)); err != nil {
		errors = append(errors, fmt.Errorf("%q: %s", k, err))
	}
	return
}
842287
func (b ValExprBuilder) RegExp(val interface{}) BoolExprBuilder {
	return b.makeComparisonExpr(astRegExp, makeValExpr(val))
}
966
func NewWithLimit(expr string, size uint) (*Regexp, error) {
	parsed, err := syntax.Parse(expr, syntax.Perl)
	if err != nil {
		return nil, err
	}
	return NewParsedWithLimit(expr, parsed, size)
}
1294841
func matchRegex(re *syntax.Regexp) ([]string, bool) {
	// Exit if we see a case-insensitive flag as it is not something we support at this time.
	if re.Flags&syntax.FoldCase != 0 {
		return nil, false
	}

	switch re.Op {
	case syntax.OpLiteral:
		// We can rewrite this regex.
		return []string{string(re.Rune)}, true
	case syntax.OpCapture:
		return matchRegex(re.Sub[0])
	case syntax.OpConcat:
		// Go through each of the subs and concatenate the result to each one.
		names, ok := matchRegex(re.Sub[0])
		if !ok {
			return nil, false
		}

		for _, sub := range re.Sub[1:] {
			vals, ok := matchRegex(sub)
			if !ok {
				return nil, false
			}

			// If there is only one value, concatenate it to all strings rather
			// than allocate a new slice.
			if len(vals) == 1 {
				for i := range names {
					names[i] += vals[0]
				}
				continue
			} else if len(names) == 1 {
				// If there is only one value, then do this concatenation in
				// the opposite direction.
				for i := range vals {
					vals[i] = names[0] + vals[i]
				}
				names = vals
				continue
			}

			// The long method of using multiple concatenations.
			concat := make([]string, len(names)*len(vals))
			for i := range names {
				for j := range vals {
					concat[i*len(vals)+j] = names[i] + vals[j]
				}
			}
			names = concat
		}
		return names, true
	case syntax.OpCharClass:
		var sz int
		for i := 0; i < len(re.Rune); i += 2 {
			sz += int(re.Rune[i+1]) - int(re.Rune[i]) + 1
		}

		names := make([]string, 0, sz)
		for i := 0; i < len(re.Rune); i += 2 {
			for r := int(re.Rune[i]); r <= int(re.Rune[i+1]); r++ {
				names = append(names, string([]rune{rune(r)}))
			}
		}
		return names, true
	case syntax.OpAlternate:
		var names []string
		for _, sub := range re.Sub {
			vals, ok := matchRegex(sub)
			if !ok {
				return nil, false
			}
			names = append(names, vals...)
		}
		return names, true
	}
	return nil, false
}
1332790
func LiteralPrefix(s *syntax.Regexp) string {
	// traverse the left-most branch in the parse tree as long as the
	// node represents a concatenation
	for s != nil && s.Op == syntax.OpConcat {
		if len(s.Sub) < 1 {
			return ""
		}

		s = s.Sub[0]
	}

	if s.Op == syntax.OpLiteral {
		return string(s.Rune)
	}

	return "" // no literal prefix
}
554136
func CloneRegexLiteral(r *RegexLiteral) *RegexLiteral {
	if r == nil {
		return nil
	}

	clone := &RegexLiteral{}
	if r.Val != nil {
		clone.Val = regexp.MustCompile(r.Val.String())
	}

	return clone
}
330508
func GetRegex(pattern string) (*regexp.Regexp, error) {
	pattern = strings.Replace(pattern, ".", "\\.", -1) // Escape all '.' in the pattern
	pattern = strings.Replace(pattern, "(", "\\(", -1) // Escape all '(' in the pattern
	pattern = strings.Replace(pattern, ")", "\\)", -1) // Escape all ')' in the pattern
	pattern = strings.Replace(pattern, "*", ".*", -1)  // Replace a '*' with '.*' that matches zero or more characters
	pattern = strings.Replace(pattern, "{", "(", -1)   // Change a '{' to '('
	pattern = strings.Replace(pattern, ",", "|", -1)   // Change a ',' to '|'
	pattern = strings.Replace(pattern, "}", ")", -1)   // Change a '}' to ')'
	pattern = strings.Replace(pattern, "?", ".", -1)   // Change a '?' to '.'
	pattern = "^" + pattern + "$"
	return regexp.Compile(pattern)
}