Matchers

The goal of matchers is to transform tokens into output. That’s where NSRE is pretty different from any other regular expression engine: tokens are not necessarily validated as-is. Instead, the matcher can decide how it likes them and the Match objects that your receive after the completion of the matching not contain the original tokens but rather the matched text.

Now you’re like, what the fuck?

Let’s have a look.

from nsre import *

f = Final(OutOf("f"))
o = Final(OutOf("o"))
b = Final(OutOf("b"))
a = Final(OutOf("a"))
r = Final(OutOf("r"))

data = [
    ('f', 'b'),
    ('o', 'a'),
    ('o', 'r'),
]

re = RegExp.from_ast(((f + o + o) | (b + a + r))["capture"])

m = re.match(data, join_trails=True)
assert {mm["capture"].trail for mm in m} == {"foo", "bar"}

As you can see, we use the OutOf matcher, which helps selecting the right token out of a series of presented tokens.

The data passed into the regular expression is not, as you usually would expect, a string but rather a sequence of tuples that each contain several letters.

The engine will match either "foo" either "bar" if it can be found in the data, or both at the same time if both are found.

Reference

There is a lot more matchers than this which all do some specific things.

class nsre.matchers.Matcher
class nsre.matchers.Eq(ref: Tok)
class nsre.matchers.In(ref: Sequence[Tok])
class nsre.matchers.OutOf(ref: Tok)
class nsre.matchers.AttributeHasValue(attribute: str, value: Any)
class nsre.matchers.KeyHasValue(key: Any, value: Any)
class nsre.matchers.Anything
class nsre.matchers.ChrRanges(*ranges: Tuple[str, str])
class nsre.matchers.Test(test: Callable[[Tok], bool])

Runs an arbitrary test and matches the token as-is if successful

class nsre.matchers.Not(matcher: Union[nsre.matchers.Matcher, Final])

Negates another matcher. If no match is found then the token is returned as-is.