36

I'm trying to extract whatever data inside ${}.

For example, the data extracted from this string should be abc.

git commit -m '${abc}'

Here is the actual code:

re := regexp.MustCompile("${*}")
match := re.FindStringSubmatch(command)

But that doesn't work, any idea?

6 Answers 6

58

In regex, $, { and } have special meaning

$ <-- End of string
{} <-- Contains the range. e.g. a{1,2}

So you need to escape them in the regex. Because of things like this, it is best to use raw string literals when working with regular expressions:

re := regexp.MustCompile(`\$\{([^}]*)\}`)
match := re.FindStringSubmatch("git commit -m '${abc}'")
fmt.Println(match[1])

Golang Demo

With double quotes (interpreted string literals) you need to also escape the backslashes:

re := regexp.MustCompile("\\$\\{(.*?)\\}")
Sign up to request clarification or add additional context in comments.

3 Comments

A hint: using raw string literals to define a regex pattern is advisable. E.g. re := regexp.MustCompile(`\$\{(.*?)\}`)
@WiktorStribiżew its already in another answer..so i didn't updated mine
The other answer is not correct, I think. +? and *? are different quantifiers. In regex, every symbol matters and can change the output greatly.
4

Try re := regexp.MustCompile(\$\{(.*)\}) * is a quantifier, you need something to quantify. . would do as it matches everything.

2 Comments

.* is a greedy subpattern and can overfire. Use with caution. It might work only with the current example, but not in real life scenario.
I didn't say it wasn't, he wanted to know why his expression didn't work, I told him why.
2

You can try with this too,

re := regexp.MustCompile("\\$\\{(.*?)\\}")

str := "git commit -m '${abc}'"
res := re.FindAllStringSubmatch(str, 1)
for i := range res {
    //like Java: match.group(1)
    fmt.Println("Message :", res[i][1])
}

GoPlay: https://play.golang.org/p/PFH2oDzNIEi

Comments

1

For another approach, you can use os.Expand:

package main
import "os"

func main() {
   command := "git commit -m '${abc}'"
   var match string
   os.Expand(command, func(s string) string {
      match = s
      return ""
   })
   println(match == "abc")
}

https://golang.org/pkg/os#Expand

Comments

1

You can use named group to extract the value of a string.

import (
    "fmt"
    "regexp"
)

func main() {
    command := "git commit -m '${abc}'"

    r := regexp.MustCompile(`\$\{(?P<text>\w+)\}`)
    subMatch := r.FindStringSubmatch(command)

    fmt.Printf("text : %s", subMatch[1])
}

GoPlay

Comments

0

Because $, { and } all have special meaning in a regex and need to be backslashed to match those literal characters, because * doesn't work that way, and because you didn't actually include a capturing group for the data you want to capture. Try:

re := regexp.MustCompile(`\$\{.+?)\}`)

1 Comment

The * in the OP pattern makes me think that the string inside {} can be empty. Thus, rock's answer seems to be closer to what OP needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.