summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Henderson <dhenderson@gmail.com>2017-06-13 22:05:52 -0400
committerDave Henderson <dhenderson@gmail.com>2017-06-13 22:08:41 -0400
commit1fbfe779e6758d0f7e9143ea2a00ad050ab8c6aa (patch)
tree3a9fe080f9cd591532b5788294c13bd002246dd2
parentbc52886c7cf83bcbd4e4ae96ab4b0e2a84d527e7 (diff)
Adding regexp support
Signed-off-by: Dave Henderson <dhenderson@gmail.com>
-rw-r--r--docs/content/functions/regexp.md70
-rw-r--r--funcs.go1
-rw-r--r--funcs/regexp.go36
-rw-r--r--funcs/regexp_test.go17
-rw-r--r--regexp/regexp.go15
-rw-r--r--regexp/regexp_test.go23
-rw-r--r--test/integration/regexp.bats19
7 files changed, 181 insertions, 0 deletions
diff --git a/docs/content/functions/regexp.md b/docs/content/functions/regexp.md
new file mode 100644
index 00000000..c97a81a8
--- /dev/null
+++ b/docs/content/functions/regexp.md
@@ -0,0 +1,70 @@
+---
+title: regexp functions
+menu:
+ main:
+ parent: functions
+---
+
+## `regexp.Replace`
+
+Replaces matches of a regular expression with the replacement string. The syntax
+of the regular expressions accepted is [Go's `regexp` syntax](https://golang.org/pkg/regexp/syntax/#hdr-Syntax),
+and is the same general syntax used by Perl, Python, and other languages.
+
+### Usage
+
+```go
+regexp.Replace expression replacement input
+```
+```go
+input | regexp.Replace expression replacement
+```
+
+### Arguments
+
+| name | description |
+|--------|-------|
+| `expression` | The regular expression string |
+| `replacement` | The replacement string |
+| `input` | the input string to operate on |
+
+### Examples
+
+```console
+$ gomplate -i '{{ regexp.Replace "(foo)bar" "$1" "foobar"}}'
+foo
+```
+
+```console
+$ gomplate -i '{{ regexp.Replace "(?P<first>[a-zA-Z]+) (?P<last>[a-zA-Z]+)" "${last}, ${first}" "Alan Turing"}}'
+Turing, Alan
+```
+
+## `regexp.Match`
+
+Returns `true` if a given regular expression matches a given input string.
+
+This returns a boolean which can be used in an `if` condition, for example.
+
+### Usage
+
+```go
+regexp.Match expression input
+```
+```go
+input | regexp.Match expression
+```
+
+### Arguments
+
+| name | description |
+|--------|-------|
+| `expression` | the regular expression to match |
+| `input` | the input string to test |
+
+### Examples
+
+```console
+$ gomplate -i '{{ if (.Env.USER | regexp.Match `^h`) }}username ({{.Env.USER}}) starts with h!{{end}}'
+username (hairyhenderson) starts with h!
+```
diff --git a/funcs.go b/funcs.go
index 6a1504de..7d38ef22 100644
--- a/funcs.go
+++ b/funcs.go
@@ -54,5 +54,6 @@ func initFuncs(data *Data) template.FuncMap {
funcs.AWSFuncs(f)
funcs.AddBase64Funcs(f)
funcs.AddNetFuncs(f)
+ funcs.AddReFuncs(f)
return f
}
diff --git a/funcs/regexp.go b/funcs/regexp.go
new file mode 100644
index 00000000..8b5983a7
--- /dev/null
+++ b/funcs/regexp.go
@@ -0,0 +1,36 @@
+package funcs
+
+import (
+ "sync"
+
+ "github.com/hairyhenderson/gomplate/regexp"
+)
+
+var (
+ reNS *ReFuncs
+ reNSInit sync.Once
+)
+
+// ReNS -
+func ReNS() *ReFuncs {
+ reNSInit.Do(func() { reNS = &ReFuncs{} })
+ return reNS
+}
+
+// AddReFuncs -
+func AddReFuncs(f map[string]interface{}) {
+ f["regexp"] = ReNS
+}
+
+// ReFuncs -
+type ReFuncs struct{}
+
+// Replace -
+func (f *ReFuncs) Replace(re, replacement, input string) string {
+ return regexp.Replace(re, replacement, input)
+}
+
+// Match -
+func (f *ReFuncs) Match(re, input string) bool {
+ return regexp.Match(re, input)
+}
diff --git a/funcs/regexp_test.go b/funcs/regexp_test.go
new file mode 100644
index 00000000..31671da0
--- /dev/null
+++ b/funcs/regexp_test.go
@@ -0,0 +1,17 @@
+package funcs
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestReplace(t *testing.T) {
+ re := &ReFuncs{}
+ assert.Equal(t, "hello world", re.Replace("i", "ello", "hi world"))
+}
+
+func TestMatch(t *testing.T) {
+ re := &ReFuncs{}
+ assert.True(t, re.Match(`i\ `, "hi world"))
+}
diff --git a/regexp/regexp.go b/regexp/regexp.go
new file mode 100644
index 00000000..8aeaa43c
--- /dev/null
+++ b/regexp/regexp.go
@@ -0,0 +1,15 @@
+package regexp
+
+import stdre "regexp"
+
+// Replace -
+func Replace(expression, replacement, input string) string {
+ re := stdre.MustCompile(expression)
+ return re.ReplaceAllString(input, replacement)
+}
+
+// Match -
+func Match(expression, input string) bool {
+ re := stdre.MustCompile(expression)
+ return re.MatchString(input)
+}
diff --git a/regexp/regexp_test.go b/regexp/regexp_test.go
new file mode 100644
index 00000000..15adccd4
--- /dev/null
+++ b/regexp/regexp_test.go
@@ -0,0 +1,23 @@
+package regexp
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestReplace(t *testing.T) {
+ assert.Equal(t, "-T-T-", Replace("a(x*)b", "T", "-ab-axxb-"))
+ assert.Equal(t, "--xx-", Replace("a(x*)b", "$1", "-ab-axxb-"))
+ assert.Equal(t, "---", Replace("a(x*)b", "$1W", "-ab-axxb-"))
+ assert.Equal(t, "-W-xxW-", Replace("a(x*)b", "${1}W", "-ab-axxb-"))
+
+ assert.Equal(t, "Turing, Alan", Replace("(?P<first>[a-zA-Z]+) (?P<last>[a-zA-Z]+)", "${last}, ${first}", "Alan Turing"))
+}
+
+func TestMatch(t *testing.T) {
+ assert.True(t, Match(`^[a-z]+\[[0-9]+\]$`, "adam[23]"))
+ assert.True(t, Match(`^[a-z]+\[[0-9]+\]$`, "eve[7]"))
+ assert.False(t, Match(`^[a-z]+\[[0-9]+\]$`, "Job[48]"))
+ assert.False(t, Match(`^[a-z]+\[[0-9]+\]$`, "snakey"))
+}
diff --git a/test/integration/regexp.bats b/test/integration/regexp.bats
new file mode 100644
index 00000000..17b5a743
--- /dev/null
+++ b/test/integration/regexp.bats
@@ -0,0 +1,19 @@
+#!/usr/bin/env bats
+
+load helper
+
+tmpdir=$(mktemp -u)
+
+function setup () {
+ mkdir -p $tmpdir
+}
+
+function teardown () {
+ rm -rf $tmpdir || true
+}
+
+@test "'regexp.Replace'" {
+ gomplate -i '{{ "1.2.3-59" | regexp.Replace `-([0-9]*)` `.$1` }}'
+ [ "$status" -eq 0 ]
+ [[ "${output}" == "1.2.3.59" ]]
+}