JSON patterns
Every programmer knows regular expressions, and how useful they
are for matching simple or complex patterns within text (that is,
within strings). MyPatterns implement a generalized form of pattern
matching, for any data structures, beyond solely strings. This is
achieved by using "JSON patterns", an integration of two well-known
notations: JSON and regular expressions.
In myPatterns, any standard regular expression (as defined in Java or
JavaScript, respectively), enclosed between slashes, can be used to
match a string. For example, the pattern /bla/ matches any string
containing the substring "bla", at any position; the pattern /^(bla
*){3,}/ matches any string starting with at least three "bla",
separated by some whitespace, etc.
For matching any other kinds of data (than strings), myPatterns also
uses a standard notation familiar to many programmers: JSON
(JavaScript Object Notation), rather than defining a whole new
notation. JSON is classically used only for data interchange
(serializing data to, and deserializing data from, a bit string), but
myPatterns slightly extends it for matching (i.e. selecting and
decomposing) data, in the following ways:
- The '%' character can be used to denote a pattern variable,
which may match any value (a scalar, an object, or a list). For
example, the pattern [1,%x,%y] matches any list of three values
starting with the integer 1, and saves the other values as pattern
variables (or "metavariables") x and y; the pattern {a:%x,b:2}
matches any object having at least two fields a and b, the former
containing any value and the latter containing the integer 2.
- Regexes, between slashes, can be used to match a string value,
besides the standard JSON notation for constant strings (between
double quotes); as a minor but useful extension, constant strings
can also be enclosed by single quotes. For example, the standard
notation "abc" is equivalent to both 'abc' and /^abc$/.
- The '|' character can be used to delimit the tail of a list,
containing any number of values. For example, the pattern [1,2|%t]
matches any list of values starting with the integers 1 and 2, and
saves the rest of the list as metavariable t.
By nesting several patterns, one can build complex queries. For
instance, the pattern [{size:/^(X*L)$/,price:%p}|%t] matches a list
starting with an article of size L or XL or XXL, etc., and saves: the
article size (because of the matching group in the regex) as
metavariable 0 (zero), the article price as metavariable p, and the
list of subsequent articles as metavariable t.