Hello, dear regexp writers! For about 5 months now, we've been working really hard or rewriting prepared patterns, in order to introduce certain necessary features to them.
The biggest issue, of prepared patterns in their current form, is that the only form of ignoring a placeholder in a pattern was escape.
Of course, you could also escape the slash, so
foo:\\@ would include the value,
wouldn't, and so on.
The that's fine, but it's not everything. There are other cases whether placeholders needed
special treatments, most notably
We knew about those cases, and we made sure, that while the placeholder would be used in those
cases, they wouldn't break the pattern and wouldn't introduce any unexpected behaviour.
So in other words, as long as the users used the library according to the documentation, every thing would be fine and every feature would be usable as usual.
The problem appears, what if user uses the library not in accordance to the documentation?
Well, the best case would be to throw an exception, where users' actions were invalid, or
perform them if they were. Sadly, it turns out that with the current implementation that appeared
to be impossible. And there's also another case, where user can use in-pattern structures to
enable or disable
x flag, turning a certain pattern into a comment, or turn a comment off.
In that, handling the placeholder properly turned out to be virtually impossible, not for the
corner cases but for the standard cases as well. So we decided to spend months, to rewrite the
prepared patterns internals, allowing us to handle the pattern building process much better.
The changes haven't been released yet, but they will be soon. Here are the changes:
\@would be left untouched. This behaviour is unchanged.
\c@would be injected. These values won't be injected now.
- Currently, placeholder
@in comment would be injected. From now on, it won't, regardless of flags used in the main pattern, or in any of the subpatterns.
So in short, in the current version,
@ placeholder was replaced everytime, unless escaped.
In this the next release,
@ will be replaced only if that's a literal in a pattern. So, if
@ is a part of a character-class (
[@]), is quoted (
\Q@\E), is escaped
\@, is in a comment
(?#@)), or is in an extended comment (
x flag is used), then it won't be injected,
or any other case to come, it won't be injected.
Hello, dear regexp writers! Again! After the revamp of prepared patterns, there will come a change in the interface of the prepared patterns method as well. Simply speaking, we'll simplify them.
When prepared patterns, first came to be, the initial idea behind
that we could name our placeholder, so that the regular expression could become more readable.
With named placeholders we could also reuse them.
However, after a year of production use, it turns out that naming placeholders doesn't produce as much utility, as it does to compromise the robustness of the patterns. And reusing of the patterns proved to be even less frequent.
For example, instead of
one could simply use
There have been debates as to which of those approaches is "cleaner", and the majority decided
Pattern::inject() is cleaner, despite the duplication of placeholders, on the rationale
that, if the placeholder is used twice, so should the injected values.
All in all, we decided that
Pattern::bind() doesn't bring any more utility that
and there's nothing you could do with
Pattern::bind(), that you couldn't with
so we decided to remove it from the library.
Bad design of
Some time back, we introduce
Pattern::template() as a way of building patterns using a fluent builder.
You could specify a template with
& placeholders inside.
@ placeholders would be injected
with the values, while
& would be injected with patterns, like masks.
After the review of the interface, we admit that was a bad interface from the start. We didn't think it through.
We decided that two placeholders,
& were superfluous, and we could easily achieve the
same effect with just one. Additionally, we decided that we shouldn't have tied the template to the
in such a crude way.
We admit that this design was as bad as it could ever be, we hated using that in production. It must be eliminated.
Instead, the new API will look similar to this one:
Which we believe looks cleaner, is more description, conveys intention and is prone to create less bugs, in our opinions.
We've release T-Regx 0.11.0.
This is more of a maintenance release, most of our development time is hovering around inject #91 issue, and that's quite a heavy feature, requiring us to in fact rewrite our Prepared Patterns completely, and use our dedicated regular expressions parser. None of the parsers available on the internet matched our needs. It will probably be released as T-Regx 1.0, because it introduces too much breaking changes. (Actually it was realeased as 0.12.0)
Another time-consuming thing is t-regx.com website being rewritten from scratch, you can expect it in a few months.
In this release, we simplified
mask() methods, unified
PatternInterface into one being, and we added
Pcre version helper.
As of the release, as always, everything is described in ChangeLog.md on github.
We've release T-Regx 0.10.2.
Normally, when doing replacements, you always had to specify explicitly the number of them, so:
Since 0.10.2, you can skip the quantifier, and just use
any other replace methods, like so:
And they will replace every occurrence, just like
Don't worry, we don't use any kind of meta-programing with magic methods or anything. We used simple
polymorphism and design patterns (delegation and adapter in this case), so if you
Go to declaration in your IDE, you will see exactly what code is being run.
Additionally, we customized some exceptions messages. Now, depending on the nature of your exception, you will see one of these additional exception messages:
Expected to get the 3-nth element from fluent pattern, but the subject backing the feed was not matched
Expected to get the first match as integer, but subject was not matched
Expected to get the first element from fluent pattern, but the elements feed has 0 element(s)
- and more. You can see them all on github in /CleanRegex/Internal/Exception/Messages
As always, everything is described in ChangeLog.md on github.
We've release T-Regx 0.10.1.
This time, we've updated match filtering. Previously, methods
filter() used on regular match pattern,
it would filter only
Detail, and have exactly alike interface as the said match pattern
(like a filtering decorator), yet
fluent()->filter() simply removed entries from the fluent stream.
We don't like that difference.
So we renamed
match()->remaining(), since that looks more like a decorator it is,
and we added new
match()->filter() method which works like
all(), but it only returns the items
matching the predicate (like
Apart from that, we fixed a bug that was lurking in
fluent()->flatMap() (don't worry, it's gone now :), as
well as improving the
fluent()->first(). Now, when filtering a fluent stream, calling
first() first calls
preg_match(), and if it matches the predicate, that
Detail is simply returned. If the first
isn't matched by the predicate, then it calls
preg_match_all() and returns the first detail
from that, that matches the predicate.
As always, everything is described in ChangeLog.md on github.
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.
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
are a simplification of
counting(), which simply validate whether the replacements performed
match the expectations.
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.
We're making big steps towards PHP 8!
We're in a process of rewriting our documentation with the changes and suggestions to use
From now on, the first couple of versions include deprecated
Match, as well
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:
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
As always, everything is described in ChangeLog.md on GitHub.