为了账号安全,请及时绑定邮箱和手机立即绑定

将 json 字段解组为 *regexp.Regexp 类型的结构字段

将 json 字段解组为 *regexp.Regexp 类型的结构字段

Go
梵蒂冈之花 2022-06-13 15:23:59
我正在尝试将带有一些基于正则表达式的规则的 JSON 文件解组到我的结构中。见下面我的结构。// GithubProjectMatcher matches a repository with a projecttype GithubProjectMatcher struct {    Rules map[string]GithubProjectMatcherRule `json:"rules,omitempty"`}// GithubProjectMatcherRule rule that matches a repository to a projecttype GithubProjectMatcherRule struct {    URL *regexp.Regexp `json:"url,omitempty"`}在这里看到我的 json{  "rules": {    "Project One": { "url": "tabia|varys|garo" },    "Project Two": { "url": "(?i)lem\\-" },  }}如果我在代码中硬编码这些正则表达式,它们就可以工作。例如regexp.MustCompile("tabia|varys|garo")必须做什么才能将这些解码到我的结构中?我尝试如下解码。f, err := os.Open("rules.json")if err != nil {   return err}defer f.Close()err := json.NewDecoder(f).Decode(&m)if err != nil {   return err}
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

解决方法如下:


通过实现 TextMarshaler 和 TextUnmarshaler 接口,您可以定义一个值应该如何被编组或解组。


https://golang.org/pkg/encoding/#TextMarshaler https://golang.org/pkg/encoding/#TextUnmarshaler


// GithubMetadataFactory allows to provide a custom generated metadata

type GithubMetadataFactory func(repo github.Repository) Metadata


// GithubProjectMatcher matches a repository with a project

type GithubProjectMatcher struct {

    Rules map[string]GithubProjectMatcherRule `json:"rules,omitempty"`

}


// GithubProjectMatcherRule rule that matches a repository to a project

type GithubProjectMatcherRule struct {

    URL *Regexp `json:"url,omitempty"`

}



// Regexp adds unmarshalling from json for regexp.Regexp

type Regexp struct {

    *regexp.Regexp

}


// UnmarshalText unmarshals json into a regexp.Regexp

func (r *Regexp) UnmarshalText(b []byte) error {

    regex, err := regexp.Compile(string(b))

    if err != nil {

        return err

    }


    r.Regexp = regex


    return nil

}


// MarshalText marshals regexp.Regexp as string

func (r *Regexp) MarshalText() ([]byte, error) {

    if r.Regexp != nil {

        return []byte(r.Regexp.String()), nil

    }


    return nil, nil

}

有关 Go Playground 中的完整示例,请参见此处。https://play.golang.org/p/IS60HuuamLM


对于更复杂的数据类型,您还可以在您的类型上实现 json Marshaler 和 Unmarshaler 接口。


https://golang.org/pkg/encoding/json/#Marshaler https://golang.org/pkg/encoding/json/#Unmarshaler


两者的例子也可以在这里找到。


https://golang.org/pkg/encoding/json/


查看完整回答
反对 回复 2022-06-13
?
GCT1015

TA贡献1827条经验 获得超4个赞

(取消)编组正则表达式非常容易。它只需要创建一个嵌入的自定义类型regexp.Regexp:


import "regexp"


// MyRegexp embeds a regexp.Regexp, and adds Text/JSON

// (un)marshaling.

type MyRegexp struct {

    regexp.Regexp

}


// Compile wraps the result of the standard library's

// regexp.Compile, for easy (un)marshaling.

func Compile(expr string) (*MyRegexp, error) {

    re, err := regexp.Compile(expr)

    if err != nil {

        return nil, err

    }

    return &MyRegexp{*re}, nil

}


// UnmarshalText satisfies the encoding.TextMarshaler interface,

// also used by json.Unmarshal.

func (r *MyRegexp) UnmarshalText(text []byte) error {

    rr, err := Compile(string(text))

    if err != nil {

        return err

    }

    *r = *rr

    return nil

}


// MarshalText satisfies the encoding.TextMarshaler interface,

// also used by json.Marshal.

func (r *MyRegexp) MarshalText() ([]byte, error) {

    return []byte(r.String()), nil

}


查看完整回答
反对 回复 2022-06-13
  • 2 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信