T Regx Versions Save

Simple library for regular expressions in PHP.

0.9.9

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its fifth beta version! Despite the beta suffix, it's 100% suitable for production use. This time, we added some security fixed and performed some throughout internal changes to prepare ourselves for the big changes, later down the track.

The detailed list of changes is in ChangeLog.md.

Security fixes

  • We handled the PHP bug #77827 - if you use T-Regx API, you don't have to worry about it :) it's handled under the hood.
  • We added support for x - extended flag in prepared patterns
  • We saw a lot of people using preg_quote() incorrectly (passing more than one character to it), so now preg::quote() throws \InvalidArgumentException for more than one character passed to preg::quote().

Summary

  • Breaking changes
    • Renamed pattern()->delimiter() to pattern()->delimited()
  • Features
    • Add MatchGroup.equals(), that allows to compare a potentially unmatched group with a string.
    • Add pattern()->match()->group()->filter() method. #22
    • Add pattern()->replace()->by()->mapAndCallback(), which first translates a match by a dictionary (like map()), and then passes it through callback, before replacing (like callback()).
  • Bug fixes
    • Fixed a bug in Prepared patterns (PCRE mode), when using a malformed pattern caused TypeError, instead of MalformedPatternException.

The detailed list of changes is also in ChangeLog.md.

See ya later, aligator!

0.9.12

2 years ago

😢 T-Regx The Dinosaur is sad to announce that we've introduced a bug in 0.9.11 version (TypeError when no argument was passed to group()->orThrow()).

It's not a big deal, but it's something we should've caught before the release. Our bad!

Summary

  • Bug fixes
    • Fixed an occasional TypeError (Bug introduced in 0.9.11, fixed in 0.9.12)

This version of course is listed as a change in ChangeLog.md.

See ya later, aligator!

0.9.13

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its sixth beta version! Despite the beta suffix, it's 100% suitable for production use. This time, we added another higher-level API in replacing; proper handling of duplicate named groups (with /J modifier), more methods to T-Regx-specific exceptions, PHP gotchas handling and preparation for PHP 8.

The detailed list of changes is in ChangeLog.md.

Summary

  • Breaking changes

    • None! Really
  • Deprecation

    • Deprecate Match, use Detail instead.

      In preparation for PHP 8, in which match is a new keyword, we deprecate Match and ReplaceMatch. Match will become an invalid class name in PHP 8.

  • Features

    • Add pattern()->replace()->focus(group) #82

      Allows you to "focus" on a certain group while replacing, so only that one particular group will be replaced. In the future, there are plans for "focus" method that can replace an arbitrary list of groups.

    • Added proper handling of /J flag #84 The detailed list of changes is also in ChangeLog.md.

  • Other

    • Updated some exceptions' messages format; most notably, indexed groups as formatted as #2, and named groups as 'group'.
  • SafeRegex

See ya later, aligator!

0.9.14

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its seventh beta version! Despite the beta suffix, it's 100% suitable for production use. This time, we bring replacements excpectations, which allow you to declare the wanted replacements performed and formats, which lets you simplify patterns for your users to create psueudo-patterns or meta-patterns if you will.

The formats are a way of building patterns, so that you can assign tokens to regular expressions; and allow an arbitrary string (say, user input) to be used to build the final pattern, using the regular expressions.

  1. Tell your user he can use tokens, like so:

    Dear user. Type a mask, where %d is a digit, and %w is letter, %ws to include whitespace, %% to include % sign.

  2. User sends the mask ['mask' => '(search:%w,age:%d)']
  3. Using the mask
    $mask = $_GET['mask'];
    
  4. Using the mask, build a pattern (which has the same interface as Pattern::of() and Pattern::inject())
    Pattern::format($mask, [
      '%d'  => '\d+',
      '%w'  => '[a-z]+',
      '%ws' => '\s+',
      '%%'  => '%'
    ]);
    

That would be the equivalent of Pattern::of('\\(search:[a-z]+,age:\d+\\)'). Characters in $mask are treated utterly as text (totally quoted), and only the patterns on the right-hand side of the tokens are treated as regular expressions.

About the changes:

The detailed list of changes is in ChangeLog.md, and here's a summary:

  • Breaking changes

    • Rename DetailGroup.replace() to DetailGroup.substitute()
    • Rename match().groupBy().texts() to match().groupBy().all()
    • Rename exceptions
      • Rename Utf8OffsetPregException to UnicodeOffsetException
      • Rename SubjectEncodingPregException to SubjectEncodingException
      • Rename CatastrophicBacktrackingPregException to CatastrophicBacktrackingException
      • Rename RecursionLimitPregException to RecursionException
      • Rename JitStackLimitPregException to JitStackLimitException
  • Bug fixes

    • Using pattern with a trailing backslash (e.g. "(hello)\\") would throw MalformedPatternException with a really weird message, exposing the implementation details. Now the message is Pattern may not end with a trailing backslash.
    • Fix an error where optionals didn't work properly for match()->offsets()->fluent()
    • Fix an error where ReplaceDetail would return malformed modifiedSubject() for utf-8 replacements
  • Features

    • Add pattern formats and pattern templates, a new way of creating pseudo-patterns for user supplied data
    • Add match()->flatMapAssoc() #88
    • Add replace()->counting(), invoking a callback with the number of replacements performed #90
    • Add replace()->exactly(), validating that exactly this many replacements were performed #90
    • Add replace()->atLeast(), validating that at least this many replacements were performed #90
    • Add replace()->atMost(), validating that at most this many replacements were performed #90
    • Add pattern()->prune() which removes every occurrence of a pattern from subject (identical to remove()->all())
  • Other:

    • Added interface PatternStructureException which can be used to catch exceptions for errors solely in pattern structure (recursion, backtracking, jit limit).

The detailed list of changes is in ChangeLog.md.

See ya later, aligator!

0.10.0

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its eighth beta version! Despite the beta suffix, it's 100% suitable for production use. This time, we finally add support for PHP8. It's not just updating the dev-dependencies versions. Argument errors and exceptions in PHP change with version PHP8, we needed to handle them properly, so the API of T-Regx stays the same. We would hate for T-Regx users to see irregularities when they update their PHP versions from 7.4 to 8.0.

The detailed list of changes is in ChangeLog.md.

Summary

  • Breaking changes
    • Previously deprecated Match is removed from T-Regx. Please, do use Detail which was added two versions ago.
  • Other
    • T-Regx supports PHP 8.

The detailed list of changes is also in ChangeLog.md.

Rawrrrr!

0.10.1

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its ninth beta version! This time we fixed filtering items in regular matching as well as fluent()/asInt()/asArray() chains.

The detailed list of changes is in ChangeLog.md.

Summary

  • Breaking changes
    • Chainable pattern()->match()->filter() is renamed to remaining().
    • After filtering MatchPattern with remaining(), consecutive Detail.index() will no longer be reindexed, they will preserve the index() they had had before remaining().
    • match()->fluent()->filter() no longer reindexes values. To reindex, use values().
  • Bug fixes
    • Fixed a bug where fluent()->flatMap()->first() would return the array, instead of the first element
  • Features
    • Add pattern()->match()->filter() which returns only matches allowed by the predicate.
    • Add pattern()->match()->group()->asInt()
  • Other
    • pattern()->match()->fluent()->filter()->first() first calls preg_match(), and if that result doesn't match the predicate, then it calls preg_match_all().

The detailed list of changes is also in ChangeLog.md.

Rawrrrr!

0.10.2

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its tenth beta version! This time we fixed a lot of bugs and mistakes, and we added implicit all() with replacing.

The detailed list of changes is in ChangeLog.md.

Summary

  • Breaking changes
    • Rename DetailGroup to Group
    • Rename ReplaceDetailGroup to ReplaceGroup
    • Rename BaseDetailGroup to CapturingGroup
  • Features
    • Calling pattern()->replace() without all()/first()/only(), implicitly assumes all()
  • Bug fixes
    • Group name "group\n" used to be considered valid, now it's correctly being treated as invalid.
  • Other
    • ReplaceMatch is now a class, not an interface.
    • When invalid strings, error messages will now also print invisible characters, for example "Foo\n", instead of
      "Foo      
      "
      
    • Update messages and exceptions thrown in edge-cases from group()->fluent() #93

The detailed list of changes is also in ChangeLog.md.

Rawrrrr!

0.11.0

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its eleventh version! We simplified interface of templates and builders, as well as unified Pattern/PatternImpl and PatternInterface. We also added Pcre facade, allowing to read the exact version of PCRE used, regardless of PHP version.

The detailed list of changes is in ChangeLog.md.

  • Features:
    • Added Detail.usingDuplicateName().get() #101
    • Added Detail.usingDuplicateName().matched() #101
    • Method Pattern:template()->literal(string) now accepts string argument, allowing for inserting arbitrary strings into the pattern.
    • Added Pattern::builder(), which works similarly to how PatternBuilder::builder() worked.
    • Added Pattern::literal() which creates an instance of a pattern with which matches an arbitrary string exactly, even when x (EXTENDED) flag is used. To add in-pattern structures, like ^ or $, use Pattern::template()->literal().
    • Added Pattern::template()->literal(), which is a shorthand for Pattern::template()->builder()->literal()->build().
    • Added Pattern::template()->mask(), which is a shorthand for Pattern::template()->builder()->mask()->build().
    • Casting PatternInterface to string results in a delimited pattern
    • Add Pcre version helper
  • Breaking changes:
    • match()->getIterator() no longer preserves the keys of values (like all())
    • match()->group()->getIterator() no longer preserves the keys of values (like all())
    • Renamed Pattern::format() to Pattern::mask()
    • Renamed Pattern::builder()->format() to Pattern::builder()->mask()
    • Renamed Pattern::template()->format() to Pattern::template()->mask()
    • Refactored Pattern::template()->formatting() to Pattern::template()->builder()->mask()
    • Method literal() now requires argument '&', to escape & in-pattern token
    • Removed PatternBuilder::builder(). Use Pattern::builder()
    • Removed PatternBuilder::compose(). Use Pattern::compose()
    • Renamed FormatMalformedPatternException to MaskMalformedPatternException
    • Removed interface PatternInterface. Now class Pattern is both an instance of a pattern, as well as a static-factory, i.e. Pattern::of()/Pattern::inject().
  • Bug fixes
    • Pattern::template() quoted values incorrectly, when delimiter other than / or % was chosen.

The detailed list of changes is also in ChangeLog.md.

Rawrrrr!

0.12.0

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its twelfthversion! We found loose approach to @ placeholders in prepared patterns, so we had to create a dedicated regular patterns parses that works with PCRE7, PCRE8, PCRE9 and PCRE10 instroduced in PHP8 and late PHP 7.4. Using the pattern, we can distinguish @ as literal (where it can be injected with values), or in character class, quotes or comments ([@], \Q@\E and #@\n, etc.) We also found that bind() method failed to fulfill its intented purpose, so it was removed from the library, however template() and inject() remain in the library. Also, also we also strictened the rules of pattern()->forArray().

The detailed list of changes is in ChangeLog.md.

  • Features
    • We added internal regular expression parser, that's used when creating Prepared patterns. Now in-pattern structures can be properly recognized, eliminating cases of misuse. Most notablly [@], \Q@\E, \@, \c@ and others, like comment groups and comments in extended mode.
  • Breaking changes
    • Prepared patterns now use internal regular expression parser, to determine what is a placeholder and what isn't:
      • Previously, [@] would be injected. Now it's treated as "@" character-class.
      • Previously, \Q@\E would be injected. Now it's treated as @ literal.
      • Previously, \c@ would be injected. Now it's \c@ control character.
      • Previously, #@\n would be injected. Now, if x flag is used (globally, or as a subpattern), then it's treated as @ comment.
      • Previously, (?#@) would be injected. Now it's treated as @ comment.
      • Previously, \@ would be treated as @ literal. This remains unchanged.
    • Mask placeholders are no longer represented as & in templates, use @.
    • Refactored Pattern::template()->builder(). Use Pattern::template() now.
    • Removed Pattern::bind(). Use Pattern::inject() or Pattern::template()->literal().
    • Removed Pattern::prepare(). Use Pattern::inject().
    • Removed Pattern::pcre()->bind().
    • Removed Pattern::pcre()->prepare().
    • Removed Pattern::template()->bind().
  • Bug fixes
    • Correct type-error in ValidPattern.isValid() on PHP 8.1.

The detailed list of changes is also in ChangeLog.md.

Rawrrrr!

0.13.4

2 years ago

😎 T-Regx The Dinosaur is really proud to announce its release 0.13.4! We're coming to giga-big-release of 1.0.0 with big steps! From the last 0.12.0 release, we put more effort on rewriting the integer parsing, group building and more through exceptions in T-Regx.

Here's a summary of changes from 0.13.0, 0.13.1, 0.13.2, 0.13.3 and in 0.13.4.

The detailed list of changes is in ChangeLog.md.

  • Features:
    • Previously, toInt()/asInt()/isInt() assumed the numerical string was always in base 10, before mapping to int. Now, the base is passed in as an optional arugment (e.g. asInt(2)), and the default value of the argument is 10. Allowed base are 2 - 36, and allowed digits are /[0-9a-z]/i (depending on the base).
    • toInt()/asInt() now throw either NumberFormatException (as before), or NumberOverflowException, if number is well formatted, but exeeds integer size on a given architecture.
  • Breaking chages:
    • We removed match()->asArray(), because Detail.group() and Detail.namedGroup() are better suited for this job.
    • pattern()->forArray() is now strict by default.
    • Removed pattern()->remove()->all()/remove()->first(), because removing single occurrance felt weird. Now use pattern()->prune().
    • Previously filter() and remaining() would leave keys in the resulting array unchagnes (as if they treated array as dictionary/map). Now the keys are now re-indexed (as if they treat array as list). To make use of keys, use flatMap()/flatMapAssoc() or groupBy()/groupByCallback().
  • Bug fixes
    • We fixed a bug with fluent()->first(), where sometimes a silence false-negative with group being missing slipped by us. Exception GroupNotMatched was thrown, where in reallity NonexistentGroup should have been thorwn.
    • Fixed w bug where using Detail.usingDuplicateName() didn't throw NonexistentG
    • We fixed a bug with match()->asInt()->keys()->first() malformed integers didn't throw NumberFormatException
  • We now created docker images to run our Github Actions against, in order to run tests on 32-bit architecture, as well as 64-bit (which was the only option). We did this, in order to make sure that integer parsing works well for both types of integer.

The detailed list of changes is also in ChangeLog.md.

Rawrrrr!