Documentation ¶
Overview ¶
Package integerintervalexpressions is a library for parsing integer interval expressions of the form '1,3-5,7-'
Expressions of this kind are commonly seen in user-facing application contexts such as page selectors in print dialogs, field selector in the CLI `cut` tool, and so on. This library provides support for parsing and utilizing such expressions in wide variety of application contexts.
Internally, the library parses an input string into an abstract logical expression, which can be then evaluated with integer values to determine whether those values lie in any of the specified intervals. The parsed expressions do not contain any actual integer sequences, which allows for small memory usage and support for infinite ranges
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Expression ¶
type Expression struct {
// contains filtered or unexported fields
}
Expression is an abstract type containing a sequence of subexpressions describing integer intervals. An Expression instance can only be constructed by ParseExpression() from a valid expression string.
The Expression only has one useful method: Matches(int), which tells you whether the given value lies inside any of the intervals contained within the expression.
func ParseExpression ¶
func ParseExpression(input string) (Expression, error)
ParseExpression calls ParseExpressionWithOptions() with default options (see DefaultParseOptions())
Example ¶
input := "1,3-5,7-" myExpr, err := ParseExpression(input) if err != nil { fmt.Println(err) return } for i := 0; i < 10; i++ { fmt.Printf("%d: %v\n", i, myExpr.Matches(i)) }
Output: 0: false 1: true 2: false 3: true 4: true 5: true 6: false 7: true 8: true 9: true
func ParseExpressionWithOptions ¶
func ParseExpressionWithOptions(input string, opts ParseOptions) (Expression, error)
ParseExpressionWithOptions attempts to extract intervals expressions from input.
---
An intervals expression consists of sequence of individual subexpressions.
A subexpression describes a continuous range of integral values (i.e an interval). A single subexpression string contains one of the following:
- an single integer, for example "1": only the value 1.
- an integer, a dash, and another integer, for example "3-5": values 3,4 and 5.
- an integer and a dash, for example "7-": denotes all integers from 7 to infinity (i.e 7,8,9,...)
Currently the parser supports only positive integer values in subexpressions.
Additionally, the parser recognizes a subexpressions equal to "*" and interprets them as "match everything". Note that such subexpression will dominate over all others, short-circuiting the whole expression to "true".
The intervals expression is consists of subexpressions joined by a delimiter character. By default, a comma (",") is used as the delimiter (although a custom delimiter can be specified via the "ParseOptions" structure). For example, the expression "1,3-5,7-" can be understood to contain three subexpressions: "1", "3-5" and "7-".
Note that the interval expression need not contain any subexpressions, which means that "" and ",,,," are valid inputs. However, both of these parse into an Expression structure containing 0 subexpressions and are, as such, rather useless.
Semantically, a single subexpression is a predicate, and combining multiple predicates denotes a logical disjunction. The above expression thus states that we have three predicates and an overall expression:
func a(x int) { return x == 1 } // "1" func b(x int) { return x >= 3 && x <= 5 } // "3-5" func c(x int) { return x >= 7 } // "7-" func expr(x int) { return a(x) || b(x) || c(x) }
(However note that in the library internals the expressions are not actually represented this way.)
Note that the library does not support parsing expressions with spaces inside subexpressions, or between the subexpressions and delimiters. This may change in future version.
---
Return values:
In case of invalid/malformed input, the function returns an error and an empty Expression{}. The errors are constructed with fmt.Errorf, and should contain description of what exactly is wrong with the given input.
A valid input string is parsed into a populated Expression, which can then be evaluated using the associated methods.
NOTE: The resulting Expression is not guaranteed to be normalized, unless you set opts.PostProcessNormalize=true, or manually call .Normalize() on the result.
func (Expression) Matches ¶
func (e Expression) Matches(val int) bool
Matches determines whether an integer is contained within the intervals expression
For example, given
expr, _ := ParseExpression("1,3-5,7-")
the expressions
expr.Matches(1) expr.Matches(4) expr.Matches(9)
evaluate to true, while
expr.Matches(2) expr.Matches(6)
evaluate to false
This method does not require the Expression to be normalized, although normalized instances *should* allow for quicker evaluation due to reduced number of interval elements in the Expression; see .Normalize().
func (Expression) MatchesAll ¶ added in v0.1.2
func (e Expression) MatchesAll() bool
MatchesAll determines whether the Expression will match every possible input i.e if MatchesAll() == true; then Matches(x) == true for all x.
func (Expression) MatchesNone ¶ added in v0.1.2
func (e Expression) MatchesNone() bool
MatchesNone determines whether the Expression will ever match anything. i.e if MatchesNone() == true; then Matches(x) == false for all x.
Such Expressions are the result of input expression strings that contain no actual subexpressions. You may instruct the expression parser to reject such input expressions by setting ParseOptions.AllowEmptyExpression to false; the current default options also have this field set as false (see DefaultParseOptions()).
func (Expression) Normalize ¶
func (e Expression) Normalize() Expression
Normalize reduces overlapping expressions to minimum set of intervals; some new interval elements may be totally new, while others are dropped. For example, expression '1-4,2-5' should normalize to '1-5'. The method returns a new normalized Expression derived from the current one.
func (Expression) String ¶
func (e Expression) String() string
Convert Expression back to textual format.
Consider the following situation
// Assume Input is valid for brevity Expr, _ := ParseExpression(Input) Norm := Expr.Normalize()
Now, the result of Expr.String() should resemble Input. However, if Expr != Norm, then Norm.String() likely differs greatly from Input. That is, a normalized Expression is unlikely to serialize back to the original input string (unless the input was written in normalized form to begin with).
type ParseOptions ¶
type ParseOptions struct { Delimiter string PostProcessNormalize bool // Allow parsing of empty input expressions strings (e.g "" or " ")? // If false, parser will return error on empty input. // If true, empty input will result in Expression that will match nothing. AllowEmptyExpression bool }
ParseOptions adjusts how the ParseExpression function will interpret the input
func DefaultParseOptions ¶
func DefaultParseOptions() ParseOptions
DefaultParseOptions returns some sensible set of options for default usage.