PHP regular expressions brought up to modern standards.
See documentation at t-regx.com.
- Installation
- Examples
- Documentation
- T-Regx fiddle - Try online
- API
- For standard projects -
pattern()
- For legacy projects -
preg::match_all()
- For standard projects -
- Overview
- Comparison
- Plans for the future
- Sponsors
- License
Installation for PHP 7.1 and later (PHP 8 as well):
composer require rawr/t-regx
T-Regx only requires mb-string
extension. No additional dependencies or extensions are required.
Illustration of methods match()
, test()
and count()
.
$pattern = Pattern::of("ups"); // pattern("ups") also works
$matcher = $pattern->match('yay, ups');
foreach ($matcher as $detail) {
$detail->text(); // (string) "ups";
$detail->offset(); // (int) 0
}
if (!$matcher->test()) {
echo "No occurrances found";
} else {
echo "Found {$matcher->count()} occurrences";
}
Full API documentation is available at t-regx.com. List of changes is available in ChangeLog.md.
Quick links:
- Introduction - https://t-regx.com/docs/introduction
- Prepared patterns - https://t-regx.com/docs/prepared-patterns
Open T-Regx fiddle and start playing around right in your browser. Try now!
Choose the interface:
-
I choose the modern regex API:
Scroll to see -
pattern()->test()
,pattern()->match()
,pattern()->replace()
-
I choose to keep PHP methods (but protected from errors/warnings):
Scroll to see -
preg::match_all()
,preg::replace_callback()
,preg::split()
For standard projects, we suggest pattern()
. For legacy projects, we suggest preg::match_all()
.
-
Standard T-Regx
$pattern = Pattern::of("ups"); // pattern("ups") also works $matcher = $pattern->match('yay, ups'); if (!$matcher->test()) { echo "Unmatched subject :/"; } foreach ($matcher as $detail) { $detail->text(); // (string) "ups"; $detail->offset(); // (int) 0 } $pattern->replace('well, ups')->with('heck') // (string) "well, heck";
-
Legacy API
try { preg::match_all('/?ups/', 'ups', $match, PREG_PATTERN_ORDER); echo $match[0][0]; } catch (\TRegx\Exception\MalformedPatternException $exception) { echo "Invalid pattern"; }
💡 See documentation at t-regx.com
-
Using user data isn't always safe with PCRE (even with
preg_quote()
), as well as just not being that convenient to use. T-Regx provides dedicated solution for building patterns with unsafe user input. ChoosePattern::inject()
for simply including user data as literals. UsePattern::mask()
to convert user-supplied masks into full-fledged patterns, safely. UsePattern::template()
for constructing more complex patterns.function makePattern($name): Pattern { if ($name === null) { return Pattern::of("name[:=]empty"); } return Pattern::inject("name[:=]@;", [$name]); // inject $name as @ } $gibberish = "(my?name)"; $pattern = makePattern($gibberish); $pattern->test('name=(my?name)'); // (bool) true
-
- Simple methods
- T-Regx exposes functionality by simple methods, which return
int
,string
,string[]
orbool
, which aren't nullable. If you wish to do something with your match or pattern, there's probably a method for that, which does exactly and only that.
- T-Regx exposes functionality by simple methods, which return
- Strings:
- Fixing error with multibyte offset (utf-8 safe).
- Separate methods for positions:
offset()
- which returns position of a match in characters in UTF-8byteOffset()
- which returns position of a match in bytes, regardless of encoding
- Groups:
-
When using
preg::match_all()
, we receive an array, of arrays, of arrays. In contrast, T-Regx returns an array of groups:Group[]
. ObjectGroup
contains all the information about the group. -
Group errors:
- When invalid group named is used
get('!@#')
, T-Regx throws\InvalidArgumentException
. - When attempt to read a missing group, T-Regx throws
NonexistentGroupException
. - When reading a group that happens not to be matched, T-Regx throws
GroupNotMatchedException
.
- When invalid group named is used
-
- Simple methods
-
- Descriptive, simple interface
- Unicode support out-of-the-box
- No Reflection used,
No (...varargs)
,No (boolean arguments, true)
,(No flags, 1)
,[No [nested, [arrays]]]
- Inconsistencies between PHP versions are eliminated in T-Regx
-
Certain arguments cause fatal errors with
preg_()
methods, which terminate the application and can't be caught. T-Regx will predict if given argument would cause a fatal error, and will throw a catchable exception instead. -
Function should do one thing, it should do it well. A function should do exactly what you expect it to do.
-
Granted,
Pattern::of()
accepts undelimited pattern ((Foo){3,4}}
) is not suitable with other PHP libraries, which work with delimited patterns (/(Foo){3,4}/
), for example Laravel and Routing. For that case, usePcrePattern::of()
which accepts plain-old standard PHP syntax. -
- Unlike PHP methods, T-Regx doesn't use warnings/notices/errors for unexpected inputs:
try { preg::match_all('/([a3]+[a3]+)+3/', 'aaaaaaaaaaaaaaaaaaaa 3'); } catch (\TRegx\SafeRegex\Exception\CatastrophicBacktrackingException $exception) { // caught }
- Detects malformed patterns in and throws
MalformedPatternException
. This is impossible to catch withpreg_last_error()
.try { preg::match('/?ups/', 'ups'); } catch (\TRegx\Exception\MalformedPatternException $exception) { // caught }
- Not every error in PHP can be read from
preg_last_error()
, however T-Regx throws dedicated exceptions for those events.
- Unlike PHP methods, T-Regx doesn't use warnings/notices/errors for unexpected inputs:
or
Current development priorities, regarding release of 1.0:
- Separate SafeRegex and CleanRegex into to two packages, so users can choose what they need #103
- Add documentation to each T-Regx public method #17 [in progress]
- Revamp of t-regx.com documentation [in progress]
- Release 1.0
- Andreas Leathley - developing SquirrelPHP
- BarxizePL - Thanks!
T-Regx is MIT licensed.