Release 0.9.7 - Match as vanilla array!

There was a lot of changes in the code, so I reckon we could release twice in the same week, because why not :)

So what are the changes?

Bare with me.

The concept

Capturing groups in T-Regx have a really rich API (probably the richest out there), with a lot of variables. Most importantly T-Regx handles:

  • Invalid groups (e.g. negative index -1 or malformed group !@#$), which always throw exception
  • Missing groups (e.g. group 4 used in pattern, that only has 2 groups; same for named) which conditionally throws exceptions
  • Optional groups (e.g. (origin/)?master), which is really tricky to distinguish with PCRE
  • Matched groups (which can be tricky, if the matched group is an empty string "")

Because of that, syntax of groups is not the shortest:

pattern('(origin/)?master')->match('master')->first(function (Match $match) {
$match->group(1)->text(); // for example

But we know that T-Regx users mostly care about the last group, Matched groups, so they would like to use them with as simple syntax as possible. That makes sense.

The idea

At first, there was an idea of Match details implementing \ArrayAccess, so this syntax would be possible:

pattern('(origin/)?master')->match('master')->first(function (Match $match) {
$match[1]; // same as above

Well, that syntax does look good, at first, but it comes at a price. A high price.

Why we ditched the \ArrayAccess idea:

  • Unnecessary set and unset methods
  • Methods that work for arrays (array_key_exist()) won't work with \ArrayAccess
  • empty($match[1]) returns true, even if the group 1 was matched ("" and "0" yes is falsy)
  • isset($match[-2]) couldn't throw an exception for a malformed group
  • There's a bug in PHP, that causes $match['100'] to be treated as $match[100] (cast to int any numeric value).

The solution

So, instead, we got an idea: What if $match was a real PHP array. Every method or notation that works for arrays, will also work.

pattern('(origin/)?master')->match('master')->asArray()->first(function (array $match) {
$match[1]; // same as above

The structure of the array is perfectly identical to what preg_match() would return :)