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.