subexpnames

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2024 License: MIT Imports: 2 Imported by: 0

README

SubExpNames

Go Report Card Go Reference Release

Documentation

You can find the generated go doc here.

Motivation

Working with regular expressions in Go can be challenging, especially when it comes to handling named capture groups in a hierarchical manner. The standard regexp package provides basic support for matching patterns and extracting groups, but it falls short when dealing with complex expressions where named groups are nested or repeated.

The subexpnames package is designed to bridge this gap. It offers an intuitive way to work with named groups in regular expressions, allowing developers to retrieve matched values in the same hierarchical structure as defined in the expression. This makes it easier to parse and manipulate data captured by complex regex patterns, simplifying tasks that would otherwise require cumbersome manual processing.

By providing a more user-friendly interface for dealing with named groups, subexpnames aims to enhance the usability of regular expressions in Go, enabling developers to focus more on their core logic and less on the intricacies of pattern matching.

Usage

For more examples look at example_test.go

package main

import (
	"fmt"
	"github.com/thetechpanda/subexpnames"
)

func main() {
	// a regular expression to match a date
	re := regexp.MustCompile(`(?P<overlap>(?P<year>(?P<thousands>\d)(?P<hundreds>\d)(?P<tens>\d)(?P<ones>\d))-(?P<month>(?P<tens>\d)(?P<ones>\d)))-(?P<overlap>(?P<day>(?P<tens>\d)(?P<ones>\d)))`)
	// a subject to match the regular expression
	subject := "this is a test subject to see if we can parse 2016-01-02 and 1234-56-78 using the Match() function."

	match, ok := subexpnames.Match(re, subject)
	if !ok {
		return
	}

	keys := []string{"overlap", "year"}
	if v, ok := match.Get(0, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year] = 2016
	}
	if v, ok := match.Get(1, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year] = 1234
	}
}

Code coverage

$ go test -cover ./...
ok      github.com/thetechpanda/subexpnames     0.268s  coverage: 100.0% of statements

Installation

go get github.com/thetechpanda/subexpnames

Contributing

Contributions are welcome and very much appreciated!

Feel free to open an issue or submit a pull request.

License

SubExpNames is released under the MIT License. See the LICENSE file for details.

Documentation

Overview

Package subexpnames provides functions for matching regular expressions against strings and extracting match values in a hierarchical manner.

subexpnames.Match first creates a tree-like structure of matches by matching a regular expression against a subject string.

The way the package splits the regular expression into a tree-like structure is by using the regular expression's FindAllStringSubmatchIndex and FindAllStringSubmatch methods. It then finds all matches containing the start and end indexes of the match and the corresponding key and value.

Calls to Matches' functions recursively descend into the nested matchValues to find the appropriate match, for this reason using this package on large regular expressions can be slow.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type MatchValue

type MatchValue struct {
	Key    string
	Value  string
	Nested []*MatchValue
	// contains filtered or unexported fields
}

MatchValue represents a single match found in the subject string that corresponds to the regular expression. It contains the following information about the match:

  • Key: A string that identifies the match, often corresponding to a named capture group in the regular expression.
  • Value: The substring from the subject string that was matched.
  • start: The starting index of the match in the subject string.
  • end: The ending index of the match in the subject string.
  • Nested: A slice of pointers to MatchValue structs representing any nested matches. Nested matches occur when the regular expression contains capture groups within other capture groups. This allows for representing the hierarchical structure of matches in a tree-like form.

type Matches

type Matches []*MatchValue

Matches represents a collection of MatchValue pointers. It is used to store multiple matches found in a subject string that match a regular expression.

func Match

func Match(regexp *regexp.Regexp, subject string) (*Matches, bool)

Match checks if the subject string matches the provided regular expression. If a match is found, it returns a regMatch object containing the tree-like structure of matchValues. Otherwise, it returns nil and false.

Example
package main

import (
	"fmt"
	"regexp"

	"github.com/thetechpanda/subexpnames"
)

func main() {
	// a regular expression to match a date
	re := regexp.MustCompile(`(?P<overlap>(?P<year>(?P<thousands>\d)(?P<hundreds>\d)(?P<tens>\d)(?P<ones>\d))-(?P<month>(?P<tens>\d)(?P<ones>\d)))-(?P<overlap>(?P<day>(?P<tens>\d)(?P<ones>\d)))`)
	// a subject to match the regular expression
	subject := "this is a test subject to see if we can parse 2016-01-02 and 1234-56-78 using the Match() function."

	match, ok := subexpnames.Match(re, subject)
	if !ok {
		return
	}

	keys := []string{"overlap", "year"}
	if v, ok := match.Get(0, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year] = 2016
	}
	if v, ok := match.Get(1, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year] = 1234
	}

	keys = []string{"overlap", "year", "thousands"}
	if v, ok := match.Get(0, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year thousands] = 2
	}
	if v, ok := match.Get(1, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year thousands] = 1
	}
	keys = []string{"overlap", "year", "hundreds"}
	if v, ok := match.Get(0, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year hundreds] = 0
	}
	if v, ok := match.Get(1, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year hundreds] = 2
	}
	keys = []string{"overlap", "year", "tens"}
	if v, ok := match.Get(0, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year tens] = 1
	}
	if v, ok := match.Get(1, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year tens] = 3
	}
	keys = []string{"overlap", "year", "ones"}
	if v, ok := match.Get(0, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year ones] = 6
	}
	if v, ok := match.Get(1, 0, keys...); ok {
		fmt.Println(keys, "=", v) // prints [overlap year ones] = 4
	}
}
Output:

func (*Matches) Get

func (rm *Matches) Get(group int, value int, keys ...string) (string, bool)

Get retrieves the value at the specified index from the specified match. If the match, value, or keys are not found, it returns an empty string and false. The function allows for accessing specific values within a group of matches based on their keys.

func (*Matches) GetAll

func (rm *Matches) GetAll(group int, keys ...string) ([]string, bool)

GetAll retrieves all the values that match the provided keys from the specified match. If the match or keys are not found, it returns nil and false. Otherwise, it returns a slice of strings containing the matching values and true.

func (*Matches) GetFirstValueOfGroup

func (rm *Matches) GetFirstValueOfGroup(group int, keys ...string) (string, bool)

GetFirstValueOfGroup retrieves the first value of the group that matches the provided keys. If the keys sequence is not found, it returns an empty string and false. This function is a convenience method for quickly accessing the first value in a group of matches.

func (*Matches) GetGroup

func (rm *Matches) GetGroup(group int) (*MatchValue, bool)

GetGroup retrieves the match at the specified index from the Matches object. If the index is out of bounds, it returns nil and false. This function provides access to individual match groups within the collection of matches.

func (*Matches) Keys

func (rm *Matches) Keys(group int) [][]string

Keys retrieves all the keys from the specified group. It returns a slice of slices of strings containing the keys and the keys of their nested matches. If a key pair is repeated, it will only be added once.

func (*Matches) Len

func (rm *Matches) Len() int

Len returns the number of groups in the Matches object.

Jump to

Keyboard shortcuts

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