diff --git a/parser.go b/parser.go index 3dfb39ba..b4ea30d9 100644 --- a/parser.go +++ b/parser.go @@ -75,11 +75,13 @@ func parseData(raw interface{}, variablesMapping map[string]interface{}) interfa } const ( - regexVariable = `[a-zA-Z_]\w*` // variable name should start with a letter or underscore + regexVariable = `[a-zA-Z_]\w*` // variable name should start with a letter or underscore + regexFunctionName = `[a-zA-Z_]\w*` // function name should start with a letter or underscore ) var ( - regexCompileVariable = regexp.MustCompile(fmt.Sprintf(`\$\{(%s)\}|\$(%s)`, regexVariable, regexVariable)) // parse ${var} or $var + regexCompileVariable = regexp.MustCompile(fmt.Sprintf(`\$\{(%s)\}|\$(%s)`, regexVariable, regexVariable)) // parse ${var} or $var + regexCompileFunction = regexp.MustCompile(fmt.Sprintf(`\$\{(%s)\(([\$\w\.\-/\s=,]*)\)\}`, regexFunctionName)) // parse ${func1($a, $b)} ) // parseString parse string with variables diff --git a/parser_test.go b/parser_test.go index 47c84591..c1db12b3 100644 --- a/parser_test.go +++ b/parser_test.go @@ -64,6 +64,47 @@ func TestRegexCompileAbnormalVariable(t *testing.T) { } } } + +func TestRegexCompileFunction(t *testing.T) { + testData := []string{ + "${func1()}", + "${func1($a)}", + "${func1($a, $b)}", + "${func1($a, 123)}", + "${func1(123, $b)}", + "abc${func1(123, $b)}123", + } + + for _, expr := range testData { + varMatched := regexCompileFunction.FindStringSubmatch(expr) + if !assert.Len(t, varMatched, 3) { + t.Fail() + } + } +} + +func TestRegexCompileAbnormalFunction(t *testing.T) { + testData := []string{ + "${func1()", + "${func1(}", + "${func1)}", + "$func1()}", + "${1func1()}", // function name can not start with number + "${func1($a}", + "abc$func1(123, $b)}123", + // "${func1($a $b)}", + // "${func1($a, $123)}", + // "${func1(123 $b)}", + } + + for _, expr := range testData { + varMatched := regexCompileFunction.FindStringSubmatch(expr) + if !assert.Len(t, varMatched, 0) { + t.Fail() + } + } +} + func TestParseDataStringWithVariables(t *testing.T) { variablesMapping := map[string]interface{}{ "var_1": "abc",