Skip to main content

T-Regx on PHP8

Rawwrrrr!

We've release T-Regx 0.10.0.

In that change, there's only added support for PHP8, which is handling of PHP8 change in methods contracts, and removal of previously deprecated Match, since match is now a keyword in PHP.

As always, everything is described in ChangeLog.md on github.

Formats and expectations!

Heey!

We've release T-Regx 0.9.14.

We changed T-Regx quite a bit with all the breaking changes, we'll try to minimise it in the future. All the changes are listed in ChangeLog.md.

In this release we added two major new features: formats and replace expectations.

Formats, using Pattern::format() allow you to build a real regular expressions using an arbitrary "mask" or "format string".

Replacement expectations add methods to control how many replacements were performed, you can now count the amount of replacements performed with counting(), and methods exactly(), atLeast(), and atMost() are a simplification of counting(), which simply validate whether the replacements performed match the expectations.

Dark mode

Heey!

We added dark mode to the documentation page, which we know is sexy right now.

We also updated a bunch of documentation pages, and there's more on the way.

We'll try to make the documentation as rich as possible, before we split the releases of T-Regx into PHP7 and PHP8 versions.

Release 0.9.13

Bueno!

We're making big steps towards PHP 8!

In this release, apart from some cool features, we're deprecating Match, since PHP8 brings new match keyword, and on PHP8 Match is a parse error. Since now, you whould be using Detail instead.

We're in a process of rewriting our documentation with the changes and suggestions to use Detail now.

From now on, the first couple of versions include deprecated Match, as well as new Detail, so there's some time to update. We'd wish to keep the deprecation forever, to keep backwards compatibility but that's impossible! :/ There's an ugly ultimatum.

We can either:

  • Keep Match, deprecated or not; only on PHP7
  • Run it on PHP8, but without Match

We can't declare Match for backwards compatibility, because then we couldn't run it on PHP8. So once we start supporting PHP8, we stop supporting deprecated Match. We're sorry there's no other way around.

In the future, we'll release version 0.10.0, and it will support PHP8 fully; but there will no longer be Match, only Detail.

As always, everything is described in ChangeLog.md on GitHub.

Release 0.9.12 Oopsie

Heey, there and sorry!

In previous release, 0.9.11 we accidentally made replace()->by()->group()->orThrow() parameter non-optional, which resulted in TypeError error. We fixed it immediately, so here's v0.9.12 with a fix :) Nothing more. Update ASAP.

As always, everything is described in ChangeLog.md on github.

Release 0.9.11

Heey, there!

Quick summary of changes in this release:

  • Every exception extending PregException (so MalformedPatternException, CatastrophicBacktrackingPregException, etc.) have received new method getPregPattern():

    try {
    pattern('foo')->...
    } catch (\TRegx\SafeRegex\Exception\PregException $exception) {
    $exception->getPregPattern(); // '/foo/'
    }

    Some methods still throw \InvalidArgumentException, and of course that exception is unchanged.

  • We brought back Pattern::prepare() (see ChangeLog.md)

  • We added Match.tail() method, which works like offset() but returns the position of the end of the occurrence in the subject (not the start like offset()).

  • tail() also works for MatchGroup and ReplaceMatch.

  • There's also byteTail(), which returns the position in bytes, instead of characters (like byteOffset()).

  • Fixed inconsistencies

    • Duplicated pattern exception message changes offset after PHP 7.3. Since now, the messages will be identical on every PHP version.
  • Added null-safety to some replace methods. Returning null from any of those methods:

    • replace()->callback()
    • replace()->otherwise()
    • replace()->by()->group()->orElse()

    throws InvalidReturnValueException.

  • Renamed some or methods. Previously, what was used to handle the missing first value (result of findFirst()), was also used to specify the replacement of an optional, unmatched group. Sorry to say that, we made a bad decision unifying this interface, since it turns out they're not even remotely connected. What fooled us, was we referred to each as "optional" (even tough one was "optional first match", and the second was "replacement of an optional group).

    In this release, we separate the interfaces, and assign new, better names for the specification of unmatched, optional groups:

    • Renamed pattern()->replace()->by()->group() methods:
      • Renamed orThrow(string) to orElseThrow(string).
      • Renamed orIgnore() to orElseIgnore().
      • Renamed orEmpty() to orElseEmpty().
      • Renamed orReturn(string) to orElseWith(string).
      • Renamed orElse(callable) to orElseCalling(callable).
    • Renamed and added pattern()->replace()->by()->group()->map() methods:
      • Renamed orThrow(string) to orElseThrow(string).
      • Added orElseIgnore().
      • Added orElseEmpty().
      • Renamed orReturn(string) to orElseWith(string).
      • Renamed orElse(callable) to orElseCalling(callable).

As always, everything is described in ChangeLog.md on github.

Release 0.9.10

We've released T-Regx 0.9.10, where we delivered what we described in previous blog post.

There are some renames to make some methods more clear. We also added pattern()->match()->tuple() and pattern()->match()->triple() helper methods.

As always, everything is described in ChangeLog.md on github.

PS: Pattern::prepare() is removed in this release, but is restored back in 0.9.11.

Removal of Pattern::prepare()

Update#

In T-Regx 0.9.10, we decided to remove Pattern::prepare() from T-Regx.

Rationale#

Originally, the idea behind this function was quite simple. We wanted to enable quick and readable parameter binding:

Pattern::prepare(['^http://', [$domain], '/index\.php'])->test($link);

Fairly easy, at the first glance.

Its messyness becomes visible, when regular expressions become few and short, and texts are multiple and long, sometimes with alteration:

Pattern::prepare([[[$http, $https]], '://', [$domain]])->test($link);
// vs.
Pattern::prepare([[[$http, $https], '://', $domain]])->test($link);

You can see, the outer layer array combined with the [$domain] array and array for schema becomes quite hard to read. Additionally, because of alteration, it becomes even more unreadable! It was very easy to misread the parameter array with alteration array, or even regular regex with text.

The solution#

So at first, we decided to remove it from the library, but then, because of one of the users comment in GitHub issues, we decided that perhaps it would be better not to remove the method, but fix it.

In this case, fixing it would be disallowing such confusing constructs as alteration in prepared patterns. So we decided to bring back Pattern::prepare(), but remove alteration so the messy queries won't appear in the source code.

Alteration is still available for Pattern:inject() and Pattern::bind():

Pattern::inject('@://@', [[$http, $https], $domain])->test($link);
Pattern::bind('@scheme://@domain', ['scheme' => [$http, $https], 'domain' => $domain])->test($link);

PHP Quiz for you!

Quiz#

I've prepared a small quiz for you, which you can try right at the main page: t-regx.com :) The quiz is about PHP Vanilla PCRE regular expressions. It's main reason, really is to illustrate the messyness and inconsistencies in the API.

Give it a try :)

Release 0.9.8 - foreach baby, foreach!

Iterables#

Up to this point, you could either use T-Regx methods that return array, in order to iterate them, or use one of the collection methods map(), forEach(), filter(), etc.

Right now any chainable method in T-Regx is also iterate

foreach (pattern('\d+')->match('127.0.0.1') as $match) {
foreach (pattern('\d+')->match('127.0.0.1')->asInt() as $digit) {
foreach (pattern('\d+')->match('127.0.0.1')->all() as $text) {

Shorthand method#

In addition to previous release, when we added asArray() method, we also added a shorthand get() method for capturing groups.

pattern('(origin/)?master')->match('master')->first(function (Match $match) {
$match->get(1); // same as $match->group(1)->text();
});