regroup

package module
v0.0.0-...-f6bb0e0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2024 License: Apache-2.0 Imports: 7 Imported by: 52

README

regroup

Simple library to match regex expression named groups into go struct using struct tags and automatic parsing

codecov License PkgGoDev Go Report Card codeclimate

Installing

go get github.com/oriser/regroup

Example

Named groups map
package main

import (
	"fmt"
	"github.com/oriser/regroup"
)

var re = regroup.MustCompile(`(?P<duration>.*?)\s+(?P<num>\d+)\s+(?P<foo>.*)`)

func main() {
	matches, err := re.Groups("5s 123 bar")
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", matches)
}

Will output: map[duration:5s foo:bar num:123]

Single match
package main

import (
	"fmt"
	"github.com/oriser/regroup"
	"time"
)

var re = regroup.MustCompile(`(?P<duration>.*?)\s+(?P<num>\d+)\s+(?P<foo>.*)`)

type B struct {
	Str string `regroup:"foo"`
}

type A struct {
	Number        int           `regroup:"num"`
	Dur           time.Duration `regroup:"duration"`
	AnotherStruct B
}

func main() {
	a := &A{}
	if err := re.MatchToTarget("5s 123 bar", a); err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", a)
}

Will output: &{Number:123 Dur:5s AnotherStruct:{Str:bar}}

Multiple matches

You can also get all matches parsed as given target struct. The return value in this case will be an array of interfaces, you should cast it to the target type in order to access its fields.

package main

import (
	"fmt"
	"github.com/oriser/regroup"
	"time"
)

var re = regroup.MustCompile(`\s*(?P<duration>.*?)\s+(?P<num>\d+)\s+(?P<foo>.*)`)

type B struct {
	Str string `regroup:"foo"`
}

type A struct {
	Number        int           `regroup:"num"`
	Dur           time.Duration `regroup:"duration"`
	AnotherStruct B
}

func main() {
	a := &A{}
	s := `5s 123 bar1
		  1m 456 bar2
		  10h 789 bar3`
	rets, err := re.MatchAllToTarget(s, -1, a)
	if err != nil {
		panic(err)
	}
	for _, elem := range rets {
		fmt.Printf("%+v\n", elem.(*A))
	}
}

Will output:

&{Number:123 Dur:5s AnotherStruct:{Str:bar1}}
&{Number:456 Dur:1m0s AnotherStruct:{Str:bar2}}
&{Number:789 Dur:10h0m0s AnotherStruct:{Str:bar3}}
Required groups

You can specify that a specific group is required, means that it can't be empty.

If a required group is empty, an error (*regroup.RequiredGroupIsEmpty) will be returned .

package main

import (
	"fmt"
	"github.com/oriser/regroup"
	"time"
)

var re = regroup.MustCompile(`(?P<duration>.*?)\s+(?P<num>\d+)\s+(?P<foo>.*)`)

type B struct {
	Str string `regroup:"foo,required"`
}

type A struct {
	Number        int           `regroup:"num"`
	Dur           time.Duration `regroup:"duration"`
	AnotherStruct B
}

func main() {
	a := &A{}
	if err := re.MatchToTarget("5s 123 ", a); err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", a)
}

Will return an error: required regroup "foo" is empty for field "Str"

Existence Match Groups

You can check for the presence of an optional group using a bool with the exists tag.

package main

type Exist struct {
	IsAdmin bool `regroup:"is_admin,exists"`
}

func main() {
	r := MustCompile(`^(?P<name>\w*)(?:,(?P<is_admin>admin))?$`)
	parsed := &Exist{}
	if err := r.MatchToTarget("bob_smith", parsed); err != nil {
		panic(err)
	}
	fmt.Printf("%t\n", parsed.IsAdmin)
}

This example would print false. However if the input were bob_smith,admin it would print true. When using the exists tag, make ure that you regular expression has an optional group and matches all the expected input patterns.

Supported struct field types

  • time.Duration
  • bool
  • string
  • int
  • int8
  • int16
  • int32
  • int64
  • uint
  • uint8
  • uint16
  • uint32
  • uint64
  • float32
  • float64

Pointers and nested structs are also supported, both on single match and multiple matches

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CompileError

type CompileError struct {
	// contains filtered or unexported fields
}

CompileError returned on regex compilation error

func (*CompileError) Error

func (c *CompileError) Error() string

type NoMatchFoundError

type NoMatchFoundError struct{}

NoMatchFoundError indicates no regex matches for given string

func (*NoMatchFoundError) Error

func (n *NoMatchFoundError) Error() string

type NotStructPtrError

type NotStructPtrError struct{}

NotStructPtrError returned when given target is not a truct pointer

func (*NotStructPtrError) Error

func (n *NotStructPtrError) Error() string

type ParseError

type ParseError struct {
	// contains filtered or unexported fields
}

ParseError returned when the conversion to target struct field type has failed

func (*ParseError) Error

func (p *ParseError) Error() string

type ReGroup

type ReGroup struct {
	// contains filtered or unexported fields
}

ReGroup is the main ReGroup matcher struct

func Compile

func Compile(expr string) (*ReGroup, error)

Compile compiles given expression as regex and return new ReGroup with this expression as matching engine. If the expression can't be compiled as regex, a CompileError will be returned

func MustCompile

func MustCompile(expr string) *ReGroup

MustCompile calls Compile and panics if it returns an error

func (*ReGroup) Groups

func (r *ReGroup) Groups(s string) (map[string]string, error)

Groups returns a map contains each group name as a key and the group's matched value as value

func (*ReGroup) MatchAllToTarget

func (r *ReGroup) MatchAllToTarget(s string, n int, targetType interface{}) ([]interface{}, error)

MatchAllToTarget will find all the regex matches for given string 's', and parse them into objects of the same type as `targetType` argument. The return type is an array of interfaces, which every element is the same type as `targetType` argument. If no matches found, a &NoMatchFoundError error will be returned

func (*ReGroup) MatchToTarget

func (r *ReGroup) MatchToTarget(s string, target interface{}) error

MatchToTarget matches a regex expression to string s and parse it into `target` argument. If no matches found, a &NoMatchFoundError error will be returned

type RequiredGroupIsEmpty

type RequiredGroupIsEmpty struct {
	// contains filtered or unexported fields
}

RequiredGroupIsEmpty returned when a required group is empty in the re match

func (*RequiredGroupIsEmpty) Error

func (r *RequiredGroupIsEmpty) Error() string

type TypeNotParsableError

type TypeNotParsableError struct {
	// contains filtered or unexported fields
}

TypeNotParsableError returned when the type of struct field is not parsable

func (*TypeNotParsableError) Error

func (t *TypeNotParsableError) Error() string

type UnknownGroupError

type UnknownGroupError struct {
	// contains filtered or unexported fields
}

UnknownGroupError returned when given regex group tag isn't exists in compiled regex groups

func (*UnknownGroupError) Error

func (u *UnknownGroupError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL