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?

r0-
  • 2,388
  • 1
  • 24
  • 29
Alex. b
  • 669
  • 2
  • 10
  • 18

6 Answers6

56

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("\\$\\{(.*?)\\}")
Old Pro
  • 24,624
  • 7
  • 58
  • 106
rock321987
  • 10,942
  • 1
  • 30
  • 43
  • 9
    A hint: using raw string literals to define a regex pattern is advisable. E.g. [`re := regexp.MustCompile(\`\$\{(.*?)\}\`)`](https://play.golang.org/p/jK5TSUGCxt) – Wiktor Stribiżew May 19 '16 at 08:17
  • @WiktorStribiżew its already in another answer..so i didn't updated mine – rock321987 May 19 '16 at 08:18
  • 1
    The other answer is not correct, I think. `+?` and `*?` are different quantifiers. In regex, every symbol matters and can change the output greatly. – Wiktor Stribiżew May 19 '16 at 08:19
4

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

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

ULLAS K
  • 881
  • 2
  • 11
  • 24
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

Zombo
  • 1
  • 62
  • 391
  • 407
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(`\$\{.+?)\}`)
hobbs
  • 223,387
  • 19
  • 210
  • 288
  • 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. – Wiktor Stribiżew May 19 '16 at 08:18
0

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

Michaël COLL
  • 1,153
  • 13
  • 18