Issue with regex in Golang

Viewed 581

I am trying to create a regex to parse specific string .

The current string is abcd_1.263.0.15-8zz00df.yml and I want to parse only 1.263.0.15-8zz00df out of it.

Tried already with this expression "_\K.*(?=\.)" but its not working in Golan and giving me pattern error. Can someone please help with this?

4 Answers

Go uses RE2 regex engine, that does not support lookaheads, lookbehinds and other PCRE goodies like \K

See this comparison of the different regex engines.

You could however use this regex:

[^_-]+-[^.]+

See this demo.

Explained:

[^_-]+   # a character that is not "_" or "-", one or more times
-        # a literal "-"
[^.]+    # a character that is not a dot, one or more times

Just reposting one of @mkopriva's snippets with a sentence,

not everything needs to be done with regular expressions :

    s := "abcd_1.263.0.15-8zz00df.yml"

    if i := strings.IndexByte(s, '_'); i > -1 {
        s = s[i+1:]
    }
    if i := strings.LastIndexByte(s, '.'); i > -1 {
        s = s[:i]
    }

    fmt.Println(s)

playground

Edit: You can simply use the regular expression:

_(.*)\.

The * matches greedily, which means that it will match everything until the last '.' - this is exactly what you need. Your match is in group 1.


Why are you using the \K matcher? Your regular expression works like this:

_(.*)(?=\.)

and group 1 contains your match.

Note: a very helpful tool to test regular expressions is this site: https://regexr.com/

For a bit more precise match for that string format, you can use a capture group, and as there do not seem to be spaces in the string you can use \S instead of .

_(\S+)\.yml$
  • _ Match the leading underscore
  • (\S+) Capture 1+ non whitespace chars in group 1
  • \.yml Match .yml
  • $ End of string

See a regex demo.

For example

package main
import (
    "fmt"
    "regexp"
)

func main(){
    re := regexp.MustCompile(`_(\S+)\.yml$`)
    res := re.FindStringSubmatch("abcd_1.263.0.15-8zz00df.yml")
    fmt.Printf("%v", res[1])
}

Output

1.263.0.15-8zz00df

Or a broader match, capturing till before the last occurrence of the dot:

_(\S+)\.

See another regex demo.

Related