go-sprout/sprout

View on GitHub
registry/regexp/functions.go

Summary

Maintainability
A
2 hrs
Test Coverage
package regexp

import (
    "regexp"
)

// RegexQuoteMeta returns a literal pattern string for the provided string.
//
// Parameters:
//
//    s string - the string to be escaped.
//
// Returns:
//
//    string - the escaped regex pattern.
//
// Example:
//
//    {{ regexQuoteMeta ".+*?^$()[]{}|" }} // Output: "\.\+\*\?\^\$\(\)\[\]\{\}\|"
func (rr *RegexpRegistry) RegexQuoteMeta(str string) string {
    return regexp.QuoteMeta(str)
}

// RegexFind searches for the first match of a regex pattern in a string
// and returns it, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to search with.
//    str string - the string to search within.
//
// Returns:
//
//    string - the first regex match found.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ "hello world" | RegexFind "hello" }} // Output: "hello", nil
func (rr *RegexpRegistry) RegexFind(regex string, str string) (string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return "", err
    }
    return r.FindString(str), nil
}

// RegexFindAll finds all matches of a regex pattern in a string up to a
// specified limit, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to search with.
//    str string - the string to search within.
//    n int - the maximum number of matches to return; use -1 for no limit.
//
// Returns:
//
//    []string - all regex matches found.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ RegexFindAll "a.", "aba acada afa", 3 }} // Output: ["ab", "ac", "af"], nil
func (rr *RegexpRegistry) RegexFindAll(regex string, str string, n int) ([]string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return []string{}, err
    }
    return r.FindAllString(str, n), nil
}

// RegexMatch checks if a string matches a regex pattern, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to match against.
//    str string - the string to check.
//
// Returns:
//
//    bool - true if the string matches the regex pattern, otherwise false.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ RegexMatch "^[a-zA-Z]+$", "Hello" }} // Output: true, nil
func (rr *RegexpRegistry) RegexMatch(regex string, str string) (bool, error) {
    return regexp.MatchString(regex, str)
}

// RegexSplit splits a string by a regex pattern up to a specified number of
// substrings, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to split by.
//    str string - the string to split.
//    n int - the maximum number of substrings to return; use -1 for no limit.
//
// Returns:
//
//    []string - the substrings resulting from the split.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ RegexSplit "\\s+", "hello world from Go", 2 }} // Output: ["hello", "world from Go"], nil
func (rr *RegexpRegistry) RegexSplit(regex string, str string, n int) ([]string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return []string{}, err
    }
    return r.Split(str, n), nil
}

// RegexReplaceAll replaces all occurrences of a regex pattern in a string
// with a replacement string, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to replace.
//    str string - the string containing the original text.
//    replacedBy string - the replacement text.
//
// Returns:
//
//    string - the modified string after all replacements.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ RegexReplaceAll "\\d", "R2D2 C3PO", "X" }} // Output: "RXDX CXPO", nil
func (rr *RegexpRegistry) RegexReplaceAll(regex string, str string, replacedBy string) (string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return "", err
    }
    return r.ReplaceAllString(str, replacedBy), nil
}

// RegexReplaceAllLiteral replaces all occurrences of a regex pattern in a
// string with a literal replacement string, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to replace.
//    s string - the string containing the original text.
//    replacedBy string - the literal replacement text.
//
// Returns:
//
//    string - the modified string after all replacements, treating the replacement text as literal text.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ RegexReplaceAllLiteral "world", "hello world", "$1" }} // Output: "hello $1", nil
func (rr *RegexpRegistry) RegexReplaceAllLiteral(regex string, s string, replacedBy string) (string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return "", err
    }
    return r.ReplaceAllLiteralString(s, replacedBy), nil
}

// RegexFindGroups finds the first match of a regex pattern in a string and
// returns the matched groups, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to search with.
//    str string - the string to search within.
//
// Returns:
//
//    []string - the matched groups from the first regex match found.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ "aaabbb" | regexFindGroups "(a+)(b+)" }} // Output: ["aaabbb", "aaa", "bbb"], nil
func (rr *RegexpRegistry) RegexFindGroups(regex string, str string) ([]string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return []string{}, err
    }
    matches := r.FindStringSubmatch(str)
    if len(matches) == 0 {
        return []string{}, nil
    }
    return matches, nil
}

// RegexFindAllGroups finds all matches of a regex pattern in a string up
// to a specified limit and returns the matched groups, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to search with.
//    str string - the string to search within.
//    n int - the maximum number of matches to return; use -1 for no limit.
//
// Returns:
//
//    [][]string - a slice containing the matched groups for each match found.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ "aaabbb aab aaabbb" | regexFindAllGroups "(a+)(b+)" -1 }} // Output: [["aaabbb", "aaa", "bbb"], ["aab", "aa", "b"], ["aaabbb", "aaa", "bbb"]], nil
func (rr *RegexpRegistry) RegexFindAllGroups(regex string, n int, str string) ([][]string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return [][]string{}, err
    }
    matches := r.FindAllStringSubmatch(str, n)
    if len(matches) == 0 {
        return [][]string{}, nil
    }
    return matches, nil
}

// RegexFindNamed finds the first match of a regex pattern with named
// capturing groups in a string and returns a map of group names to matched
// strings, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to search with, containing named capturing groups.
//    str string - the string to search within.
//
// Returns:
//
//    map[string]string - a map of group names to their corresponding matched strings.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ "aaabbb" | regexFindNamed "(?P<first>a+)(?P<second>b+)" }} // Output: map["first":"aaa", "second":"bbb"], nil
func (rr *RegexpRegistry) RegexFindNamed(regex string, str string) (map[string]string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return map[string]string{}, err
    }
    matches := r.FindStringSubmatch(str)
    if len(matches) == 0 {
        return map[string]string{}, nil
    }

    result := make(map[string]string, len(r.SubexpNames())-1)
    for i, name := range r.SubexpNames() {
        if i != 0 && name != "" {
            result[name] = matches[i]
        }
    }
    return result, nil
}

// RegexFindAllNamed finds all matches of a regex pattern with named capturing
// groups in a string up to a specified limit and returns a slice of maps of
// group names to matched strings, with error handling.
//
// Parameters:
//
//    regex string - the regular expression to search with, containing named capturing groups.
//    str string - the string to search within.
//    n int - the maximum number of matches to return; use -1 for no limit.
//
// Returns:
//
//    []map[string]string - a slice containing a map of group names to their corresponding matched strings for each match found.
//    error - error if the regex fails to compile.
//
// Example:
//
//    {{ "aaabbb aab aaabbb" | regexFindAllNamed "(?P<first>a+)(?P<second>b+)" -1 }} // Output: [map["first":"aaa", "second":"bbb"], map["first":"aa", "second":"b"], map["first":"aaa", "second":"bbb"]], nil
func (rr *RegexpRegistry) RegexFindAllNamed(regex string, n int, str string) ([]map[string]string, error) {
    r, err := regexp.Compile(regex)
    if err != nil {
        return []map[string]string{}, err
    }
    matches := r.FindAllStringSubmatch(str, n)
    if len(matches) == 0 {
        return []map[string]string{}, nil
    }

    subexpNames := r.SubexpNames()
    results := make([]map[string]string, 0, len(matches))

    for _, match := range matches {
        m := make(map[string]string, len(subexpNames))
        for i, name := range subexpNames {
            if i != 0 && name != "" {
                m[name] = match[i]
            }
        }
        results = append(results, m)
    }
    return results, nil
}