Documentation ¶
Overview ¶
Package pattern implements template-based string matching and substitution.
A *pattern.P represents a template string containing a number of pattern words, named locations where substitution may occur. A pattern may be "matched" against a string to produce a set of bindings of names to substrings; or it may be "applied" to a set of bindings to produce a transformed string.
Template Grammar ¶
A template is a string that contains zero or more pattern words. A pattern word has the general format
${name}
That is, a single word (allowing letters, digits, "/", ":", "_", "-", "+", "=", and "#") enclosed in curly brackets, prefixed by a dollar sign ($). To include a literal dollar sign, double it ($$); all other characters are interpreted as written.
Matching ¶
Each pattern word is an anchor to a location in the template string. Binding regular expressions to the pattern words allows the the pattern to match strings.
To match a pattern against a string, use the Match method. Match succeeds if the string is a full regexp match for the expansion of the template with the pattern word bindings. A successful match returns a list of Binds that give the text of the submatches.
To find multiple matches of the pattern in the string, use the Search method. Search behaves like Match, but invokes a callback for each complete, non-overlapping match in sequence.
Substitution ¶
String values may be substituted into a pattern using the Apply and ApplyFunc methods. Apply takes an ordered list of Bind values and interpolates them into the template; ApplyFunc invokes a callback to generate the strings to interpolate.
Index ¶
- Variables
- type Bind
- type BindFunc
- type Binds
- type P
- func (p *P) Apply(binds []Bind) (string, error)
- func (p *P) ApplyFunc(f BindFunc) (string, error)
- func (p *P) Bind(binds Binds) *P
- func (p *P) Binds() Binds
- func (p *P) Derive(s string) (*P, error)
- func (p *P) Match(needle string) (Binds, error)
- func (p *P) Search(needle string, f func(start, end int, binds Binds) error) error
- func (p *P) String() string
- type ParseError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoMatch = errors.New("string does not match pattern")
ErrNoMatch is reported by Match when the pattern does not match the needle.
var ErrStopSearch = errors.New("stopped searching")
ErrStopSearch is a special error value that can be returned by the callback to Search to terminate search early without error.
Functions ¶
This section is empty.
Types ¶
type BindFunc ¶
A BindFunc synthesizes a value for the nth occurrence (indexed from 1) of a pattern word with the given name.
type Binds ¶
type Binds []Bind
Binds is an ordered collection of bindings.
type P ¶
type P struct {
// contains filtered or unexported fields
}
P contains a compiled pattern.
func MustParse ¶
MustParse parses s into a pattern template, as Parse, but panics if parsing fails. This function exists to support static initialization.
func Parse ¶
Parse parses s into a pattern template, and binds the specified pattern variables to the corresponding expressions.
Example ¶
package main import ( "fmt" "log" "github.com/creachadair/pattern" ) func main() { // A pattern consists of a template string containing pattern words, and a // set of bindings that give regular expressions that each word must match. p, err := pattern.Parse(`Grade: ${grade}`, pattern.Binds{ {Name: "grade", Expr: `([ABCD][-+]?|[EF])`}, }) if err != nil { log.Fatalf("Parse: %v", err) } // The string representation of a pattern is the original template string // from which it was parsed. fmt.Println(p) }
Output: Grade: ${grade}
func (*P) Apply ¶
Apply applies a list of bindings to the pattern template to produce a new string. It is an error if the bindings do not cover the pattern words in the template, meaning binds has at least one binding for each pattern word mentioned by the template.
If a pattern word appears in the template more often than in binds, the value of the last matching binding is repeated to fill the remaining spots.
Example ¶
package main import ( "fmt" "log" "github.com/creachadair/pattern" ) func main() { p := pattern.MustParse(`type ${name} struct { ${lhs} int ${rhs} int }`, nil) s, err := p.Apply(pattern.Binds{ {Name: "name", Expr: "binop"}, {Name: "lhs", Expr: "X"}, {Name: "rhs", Expr: "Y"}, }) if err != nil { log.Fatal(err) } fmt.Println(s) }
Output: type binop struct { X int Y int }
func (*P) ApplyFunc ¶
ApplyFunc applies bindings generated by f to the pattern template of p to produce a new string. If f reports an error, application fails. ApplyFunc will panic if f == nil.
Example ¶
package main import ( "fmt" "log" "github.com/creachadair/pattern" ) func main() { p := pattern.MustParse(`type ${name} struct { ${arg} string `+"`json:\"${arg},omitempty\"`"+` }`, nil) s, err := p.ApplyFunc(func(name string, n int) (string, error) { if name == "name" { return "Argument", nil } else if n == 1 { return "X", nil } return "value", nil }) if err != nil { log.Fatal(err) } fmt.Println(s) }
Output: type Argument struct { X string `json:"value,omitempty"` }
func (*P) Bind ¶
Bind returns a copy of p with the specified bindings updated. Existing bindings of p not mentioned in binds are copied intact from p to the result.
func (*P) Binds ¶
Binds returns a list of bindings for p, in parsed order, populated with the currently-bound expression strings. Modifying the result has no effect on p, the caller may use this to generate a list of bindings to fill with values.
func (*P) Derive ¶
Derive constructs a new compiled pattern, using the same pattern words as p but with s as the template instead. It is an error if s refers to a pattern word not known to p.
func (*P) Match ¶
Match reports whether needle matches p, and if so returns a list of bindings for the pattern words occurring in s. Because the same pattern word may occur multiple times in the pattern, the order of bindings is significant.
If matching fails, Match returns nil, ErrNoMatch. If matching succeeds but no bindings are found, Match returns nil, nil.
Example ¶
package main import ( "fmt" "log" "github.com/creachadair/pattern" ) func main() { p := pattern.MustParse(`[${text}](${link})`, pattern.Binds{ {Name: "text", Expr: ".+"}, {Name: "link", Expr: "\\S+"}, }) m, err := p.Match(`[docs](http://godoc.org/net/url)`) if err != nil { log.Fatal(err) } fmt.Printf("link text: %s\n", m.First("text")) fmt.Printf("URL: %s\n", m.First("link")) }
Output: link text: docs URL: http://godoc.org/net/url
func (*P) Search ¶
Search scans needle for all non-overlapping matches of p. For each match, Search calls f with the starting and ending offsets of the match, along with the bindings captured from the match. If f reports an error, the search ends. If the error is ErrStopSearch, Search returns nil. Otherwise Search returns the error from f.
Example ¶
package main import ( "fmt" "log" "github.com/creachadair/pattern" ) func main() { p := pattern.MustParse("${word}:", pattern.Binds{ {Name: "word", Expr: "\\w+"}, }) const text = ` Do: a deer, a female deer, Re: a drop of golden sun. Mi: a name I call myself, Fa: a long long way to run. ` if err := p.Search(text, func(i, j int, m pattern.Binds) error { fmt.Printf("At %d: %q\n", i, m.First("word")) return nil }); err != nil { log.Fatal(err) } }
Output: At 1: "Do" At 28: "Re" At 54: "Mi" At 80: "Fa"
type ParseError ¶
type ParseError struct { Pos int // offset where error occurred Message string // description of error }
ParseError is the concrete type of parsing errors.
func (*ParseError) Error ¶
func (p *ParseError) Error() string
Directories ¶
Path | Synopsis |
---|---|
Program madlib is a lighthearted demonstration program for how to use the github.com/creachadair/pattern package.
|
Program madlib is a lighthearted demonstration program for how to use the github.com/creachadair/pattern package. |
Package transform implements transformations between pairs of string patterns, as defined by the github.com/creachadair/pattern package.
|
Package transform implements transformations between pairs of string patterns, as defined by the github.com/creachadair/pattern package. |