github.com/netdata/go.d.plugin@v0.58.1/pkg/matcher/regexp.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package matcher
     4  
     5  import "regexp"
     6  
     7  // NewRegExpMatcher create new matcher with RegExp format
     8  func NewRegExpMatcher(expr string) (Matcher, error) {
     9  	switch expr {
    10  	case "", "^", "$":
    11  		return TRUE(), nil
    12  	case "^$", "$^":
    13  		return NewStringMatcher("", true, true)
    14  	}
    15  	size := len(expr)
    16  	chars := []rune(expr)
    17  	var startWith, endWith bool
    18  	startIdx := 0
    19  	endIdx := size - 1
    20  	if chars[startIdx] == '^' {
    21  		startWith = true
    22  		startIdx = 1
    23  	}
    24  	if chars[endIdx] == '$' {
    25  		endWith = true
    26  		endIdx--
    27  	}
    28  
    29  	unescapedExpr := make([]rune, 0, endIdx-startIdx+1)
    30  	for i := startIdx; i <= endIdx; i++ {
    31  		ch := chars[i]
    32  		if ch == '\\' {
    33  			if i == endIdx { // end with '\' => invalid format
    34  				return regexp.Compile(expr)
    35  			}
    36  			nextCh := chars[i+1]
    37  			if !isRegExpMeta(nextCh) { // '\' + mon-meta char => special meaning
    38  				return regexp.Compile(expr)
    39  			}
    40  			unescapedExpr = append(unescapedExpr, nextCh)
    41  			i++
    42  		} else if isRegExpMeta(ch) {
    43  			return regexp.Compile(expr)
    44  		} else {
    45  			unescapedExpr = append(unescapedExpr, ch)
    46  		}
    47  	}
    48  
    49  	return NewStringMatcher(string(unescapedExpr), startWith, endWith)
    50  }
    51  
    52  // isRegExpMeta reports whether byte b needs to be escaped by QuoteMeta.
    53  func isRegExpMeta(b rune) bool {
    54  	switch b {
    55  	case '\\', '.', '+', '*', '?', '(', ')', '|', '[', ']', '{', '}', '^', '$':
    56  		return true
    57  	default:
    58  		return false
    59  	}
    60  }