-2

essentially, I'm trying to build capture groups in golang. I'm utilizing the following web page, which seems to indicate that this should work properly as I've written it

For random reasons this is time sensitive, I'm sure you can sympathize

    package main
import (
    "fmt"
    "regexp"
)

func main() {
    var r = regexp.MustCompile(`/number(?P<value>.*?)into|field(?P<field>.*?)of|type(?P<type>.*?)$/g`)
    fmt.Printf("%#v\n", r.FindStringSubmatch(`cannot unmarshal number 400.50 into Go struct field MyStruct.Numbers of type int64`))
    fmt.Printf("%#v\n", r.SubexpNames())
}

This of course produces a result that I don't expect, which is inconsistent with the results on the regex builder website. This is probably because it was built for use with a different language, but I'm ignorant of another website that is more suited for golang that also supports building capture groups, and could use an assist on this one, as it's out of my usual wheelhouse.

the output of the above code using the regex format I have provided is

[]string{"field", "", "", ""}
[]string{"", "value", "field", "type"}

I'd love for it to be as close as possible to

[]string{"field", "cannot unmarshal number (number)", "into go struct (Mystruct.Numbers)", "of type (int64)"}
[]string{"", "value", "field", "type"}

just as it shows on the regex scratchpad above.

It would also be convenient to only match the first instance that matches.

W B
  • 1
  • 2
    The `|`s mean logical OR, which means you have 3 things it could match, and it will only match one. The tool you're using shows you everything it might match, not what it will match in a single execution. Based on your description, none of those ORs should be there. – Adrian Jun 22 '21 at 15:02

1 Answers1

1

This looks like an XY Problem.

Extract the data directly from the json.UnmarshalTypeError instead of parsing the string representation of the error.

This program:

var v MyStruct
err := json.Unmarshal([]byte(`{"numbers": 400.50}`), &v)
if e, ok := err.(*json.UnmarshalTypeError); ok {
    fmt.Printf("Value: %s\nStruct.Field: %s\nType: %s\n",
        e.Value, e.Struct+"."+e.Field, e.Type)
}

prints the output:

Value: number 400.50
Struct.Field: MyStruct.Numbers
Type: int64

Run it on the Go playground.