Kinda like the opposite of regular expressions
Regular expressions can match a pattern in a text and return the matches. However, what if we want find all texts that would match a given pattern. I created ExpExp, a PHP library, that allows you to do this.
Two years ago I have written a library for a project to generate strings based on a given pattern called ExpExp. ExpExp takes a pattern (a subset of regular expressions) and returns all strings that would match the pattern. For example, the pattern foo(bar|baz)
would expand to foobar
and foobaz
.
Last week I found the library again and I decided, mostly for fun and pleasure, to add new features and to rewrite the whole code. I also moved to code to the Braincrafted namespace. You can find it on Github.
While my goal is to support as many patterns supported by regular expressions as possible, it will ever be only a subset. For example, the star operator in regular expressions matches an infinite amount of infinite long strings. ExpExp can never support such things. Let's stop talking about what's not possible, but about the features that work right now.
Features
ExpExp currently supports the following operators:
- Parentheses
- Disjunction
- Repetition
- Alternation
- Character classes
- Dot operator
- Optional operator
I am now going to discuss these operators in more detail.
Parentheses
Pattern | Expansions |
---|---|
foo(bar) |
['foobar'] |
Disjunction
Pattern | Expansions |
---|---|
foo[abc] |
['fooa', 'foob', 'fooc'] |
Repetition
Pattern | Expansions | |
---|---|---|
foo{3} |
foo |
|
foo{1,3} |
['foo', 'foofoo', 'foofoofoo'] |
|
foo{,3} |
['', 'foo', 'foofoo', 'foofoofoo'] |
Alias for foo{0,3} |
foo(bar){2} |
foobarbar |
Alternation
Pattern | Expansions |
---|---|
foo|bar |
['foo', 'bar'] |
foo(bar|baz) |
['foobar', 'foobaz'] |
Character classes
Pattern | Expansions |
---|---|
[[:lower:]] |
['a', 'b', 'c', ..., 'z'] |
[[:lower:][:upper:]] |
['a', ..., 'z', 'A', ..., 'Z'] |
Other character classes are
Character class | Description | Regular expression |
---|---|---|
upper |
Uppercase characters | [A-Z] |
lower |
Lowercase characters | [a-z] |
digit |
Digits | [0-9] |
word |
Alphanumeric characters and underscore | [A-Za-z0-9_] |
space |
Space characters | [\t\n\r ] |
vspace |
Vertical space characters | [\n\r] |
hspace |
Horizontal space characters | [\t ] |
punct |
Punctuation characters | [!"#$%&'()*+,-./:;<=>?@[]^_{|}~`] |
There are also multiple shortcuts available:
Shortcut | Character classes |
---|---|
\d |
digit |
\w |
word |
\s |
space |
\v |
vspace |
\h |
hspace |
Dot operator
The dot operator is replaced by all characters from the word
character class.
Pattern | Expansions |
---|---|
foo. |
['fooa', 'foob', ..., 'foo_'] |
Optional operator
The optional operator allows you to make a character or the content inside a parentheses optional.
Pattern | Expansions |
---|---|
abc? |
['abc', 'ab'] |
foo(bar)? |
['foobar', 'foo'] |
Combination
Of course you can combine all of these operators. For example,
ab(cde|[xyz])
will expand to
abcde
abx
aby
abz
Use Cases
I don't think there are many use cases in real life for this library, but it was fun and challenging project.
Installation
If you want to play around with ExpExp or find a use cases in one of your project you can use Composer to install it:
{
"require": {
"braincrafted/expexp": "dev-master"
}
}
I already have tagged some versions, so you can use, for example, 0.2.*
to get a (relative) stable release.
Usage
Pass the pattern to the expand()
method and ExpExp will return an array with all expansions:
use Bc\ExpExp\ExpExp;
$e = new ExpExp();
$result = $e->expand('abc|xyz');
That's it.