Skip to content

t-regx/pattern-functions

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

T-Regx

Build status Coverage alpha: 0.1.0

T-Regx | Set of function helpers

pattern/functions is a set of helper functions, simplifying the usage of Pattern of standard T-Regx library.

See documentation at t-regx.com.

Code Climate PRs Welcome Gitter

OS Arch OS Arch OS Arch OS Arch

PHP Version PHP Version PHP Version PHP Version PHP Version PHP Version PHP Version

  1. Installation
  2. Overview
  3. Documentation
    1. Examples
      • pattern_test()
      • pattern_fails()
      • pattern_count()
      • pattern_match_first()
      • pattern_match_optional()
      • pattern_match_ref()
      • pattern_match_all()
      • pattern_replace()
      • pattern_replace_callback()
      • pattern_split()
      • pattern_cut()
      • pattern_filter()
      • pattern_reject()
      • pattern_search()
  4. API reference
    1. Exception reference
    2. Identities
  5. Frequently asked questions
  6. Comparison against preg_ functions
  7. Sponsors
  8. License

Buy me a coffee!

Installation

Installation for PHP 7.1-8.2 and later:

Package pattern/functions is an addon to rawr/t-regx.

composer require pattern/functions

Installing pattern/functions will also install core rawr/t-regx.

Currently, T-Regx composer package is named rawr/t-regx. In the future, with release 1.0 the T-Regx package will be renamed to pattern/pattern.

Overview

T-Regx library is an object-oriented approach to regular expressions, with classes Pattern, Matcher etc. Find more in "Introduction to T-Regx".

On the other hand, a simplified approach is possible with helper functions in pattern/helpers package. It adds simplified functions for an easier start with the library.

Examples with helper functions:

<?php
if (pattern_test('\w+', $_GET['subject'])) {
  $matches = pattern_match_all('\w+', $_GET['subject']);
  foreach ($matcher as $match) {
      echo "Found a match $match at position {$match->offset()}!";
  }
  echo "Occurrences found: " . pattern_count('\w+', $_GET['subject']);
} 
else {
  echo "No matches found :/";
}
return pattern_split('\w+', $_GET['subject']);
<?php
return pattern_replace('\w+', $_GET['subject'], '***');
<?php
return pattern_replace_callback('\w+', $_GET['subject'], fn (Detail $match) => '***');
<?php
try {
   $match = pattern_match_first('\w+', $_GET['subject'], fn (Detail $match) => '***');
}
catch (MalformedPatternException $exception) {
   // used improper regular expression
}
catch (CatastrophicBacktrackingException $exception) {
   // catastrophic backtracking while matching
}

Helper functions utilize the same implementation as Pattern in the core library.

Documentation

Available functions:

  • Predication:
    • pattern_test() - returns true, if pattern matches the subject
    • pattern_count() - returns number of occurrences of pattern in the subject
  • Retrieve match/matches:
    • pattern_match_first() - returns the first matched occurrence, as Detail
    • pattern_match_optional() - returns an optional matched occurrence, as Detail|null
    • pattern_match_ref() - populates &Detail via ref-argument and returns true/false
    • pattern_match_all() - returns all matched occurrences, as Detail[]
  • Replacing:
    • pattern_replace() - replaces occurrences of pattern in the subject with given string
    • pattern_replace_callback() - replaces occurrences of pattern in the subject via given callback
    • pattern_prune() - removes occurrences of pattern from the subject
  • Splitting:
    • pattern_split() - returns string[] separated by occurrences of the pattern in the subject
    • pattern_cut() - returns a two-element array separated by a single occurrence of pattern in the subject
  • Filtering array
    • pattern_filter() - accepts string[] and returns string[] with only subjects matching the pattern
    • pattern_reject() - accepts string[] and returns string[] with subjects that don't match the pattern

Scroll to "API Reference".

Scroll to "Exception Reference".

Scroll to "Frequently asked questions".

Examples

  • Check whether the pattern matches the subject:

    if (pattern_test('[A-Z][a-z]+', $_GET['username']) === true) {
    }

    Function pattern_test() is another notation of

    $pattern = Pattern::of('[A-Z][a-z]+');
    if ($pattern->test($_GET['username'])) {
    }

    Examples of error handling

    try {
      $matched = pattern_test($pattern, $subject);
    } catch (MalformedPatternException $exception) {
    } catch (CatastrophicBacktrackingException $exception) {
    } catch (SubjectEncodingException $exception) {
    } catch (RecursionException $exception) {
    }

    T-Regx library is based on exceptions, and so are helper functions. Function pattern_test() doesn't issue any warnings, notices and doesn't set any C-like status codes.

  • Retrieve the first occurrence of pattern in the subject:

    /**
     * @var Detail $match
     */
    $match = pattern_match_first('\w+', 'Welcome to the jungle');
    
    $match->text();
    $match->offset();
    $match->group(2);
    $match->toInt();

    Function pattern_match_first() is another notation of

    $pattern = Pattern::of('[A-Z][a-z]+');
    $matcher = $pattern->match($_GET['username']);
    /**
     * @var Detail $match
     */
    $match = $matcher->first();
  • Retrieve the matched occurrence of pattern in a subject, or null for an unmatched subject:

    /**
     * @var ?Detail $match
     */
    $match = pattern_match_optional('\w+', 'Welcome to the jungle');
    
    if ($match === null) {
      // pattern not matched
    } else {
      $match->text();
      $match->offset();
      $match->group(2);
      $match->toInt();
    }

    More about Detail can be found in "Match details".

  • Read matched occurrence details of pattern in a subject, and populate Detail as a reference argument:

    if (pattern_match_ref('\w+', 'Welcome to the jungle', $match)) {
      /**
       * @var Detail $match
       */
      $match->text();
      $match->offset();
      $match->group(2);
      $match->toInt();
    } else {
      // pattern not matched
    }

    More about Detail can be found in "Match details".

  • Retrieve all matched occurrences of pattern in the subject:

    /**
     * @var Detail[] $matches
     */
    $matches = pattern_match_all('\w+', 'Winter is coming');
    foreach ($matches as $match) {
    }

    Function pattern_match_all() is another notation of

    $pattern = Pattern::of('\w+');
    $matcher = $pattern->match('Winter is coming');
    $matches = $matcher->all();
    foreach ($matches as $match) {
    }
  • Replace occurrences of pattern in the subject with a given string replacement or callable:

    $slug = pattern_replace('\s+', 'We do not sow', '-');
    $slug = pattern_replace_callback('\s+', 'We do not sow', fn (Detail $match) => '-');

    Functions pattern_replace() and pattern_replace_callback() are another notation of

    $pattern = Pattern::of('\s+');
    $replace = $pattern->replace('We do not sow');
    
    $slug = $replace->with('-');
    $slug = $replace->callback(fn (Detail $match) => '-');

More about Detail can be found in "Match details".

API Reference

Predication

  • pattern_test() returns true if $pattern matches the $subject, false otherwise.
    pattern_test(string $pattern, string $subject, string $modifiers=''): bool;
  • pattern_fails() returns false if $pattern matches the $subject, true otherwise.
    pattern_fails(string $pattern, string $subject, string $modifiers=''): bool;
  • pattern_count() returns the number of occurrences of $pattern in $subject.
    pattern_count(string $pattern, string $subject, string $modifiers=''): int;

Matching

  • pattern_match_first() returns the first occurrence of pattern in the subject as Detail; throws SubjectNotMatchedException if the pattern doesn't match the subject.
    pattern_match_first(string $pattern, string $subject, string $modifiers=''): Detail;
  • pattern_match_optional() returns the first occurrence of pattern in the subject as Detail; returns null if the pattern doesn't match the subject.
    pattern_match_optional(string $pattern, string $subject, string $modifiers=''): Detail|null;
  • pattern_match_ref() returns true and populates &Detail as ref-argument with the first occurrence of pattern in the subject; returns false if the pattern doesn't match the subject.
    pattern_match_ref(string $pattern, string $subject, ?Detail &$refDetail, string $modifiers=''): bool;
  • pattern_match_all() returns all occurrences of pattern in the subject as Detail[]; returns an empty array if the pattern doesn't match the subject.
    pattern_match_all(string $pattern, string $subject, string $modifiers=''): Detail[];
  • pattern_search() returns all occurrences of pattern in the subject as string[]; returns an empty array if the pattern doesn't match the subject.
    pattern_search(string $pattern, string $subject, string $modifiers=''): array;

Replacing

  • pattern_replace() replaces all occurrences of pattern in a subject with a given replacement.
    pattern_replace(string $pattern, string $subject, string $replacement, string $modifiers=''): string;
  • pattern_replace_callback() replaces all occurrences of pattern in a subject via the specified callback. The callback is passed Detail as the only argument, and only accepts string as return type.
    pattern_replace_callback(string $pattern, string $subject, callable $callback, string $modifiers=''): string;
  • pattern_prune() removes all occurrences of pattern from a subject.
    pattern_prune(string $pattern, string $subject, string $modifiers=''): string;

Splitting

  • pattern_split() separates the subject by occurrences of pattern in the subject. If two occurrences of pattern are found in the subject next to each other, then an empty string is present in the returned array to indicate it. A part or whole separator can be included in the returned array by adding a capturing group in the pattern.
    pattern_split(string $pattern, string $subject, string $modifiers=''): string[];
  • pattern_cut() splits a subject into exactly two elements, which are returned as string[]. The separating pattern occurrence is not included in the result, pattern_cut() only returns a two-element array. If there are more occurrences of the pattern in the subject, or subject is not matched at all, then UnevenCutException is thrown.
    pattern_cut(string $pattern, string $subject, string $modifiers=''): string[];

Filtering subject lists

  • pattern_filter() accepts string[] of subjects, and returns string[] which only contains subjects which match the pattern.
    pattern_filter(string $pattern, string[] $subjects, string $modifiers=''): string[];
  • pattern_reject() accepts string[] of subjects, and returns string[] which only contains subjects which do not match the pattern.
    pattern_reject(string $pattern, string[] $subjects, string $modifiers=''): string[];

Helper for Pattern

  • pattern() is an alias for Pattern::of().
    pattern(string $pattern, string $modifiers=''): Pattern;

Exception reference

All of the functions in pattern/functions library throw the specified exceptions:

  • MalformedPatternException - when pattern is given not conforming to the regular expression syntax
  • RecursionException - when recursion limit was exhausted while matching the subject
  • CatastrophicBacktrackingException - when backtracking limit was exhausted while matching the subject
  • SubjectEncodingException - when improperly encoded subject is used in unicode-mode
  • JitStackLimitException - when JIT-compilation optimisation could not be added, due to exhausted limit

Identities

Functions in pattern/functions are thin wrappers around functionalities in core library.

  • pattern() - identical to Pattern::of()
  • pattern_test() - identical to Pattern.test()
  • pattern_fails() - identical to Pattern.fails()
  • pattern_match_first() - identical to Matcher.first()
  • pattern_match_all() - identical to Matcher.all()
  • pattern_search() - identical to Pattern.search()
  • pattern_replace() - identical to Replace.with()
  • pattern_replace_callback() - identical to Replace.callback()
  • pattern_prune() - identical to Pattern.prune()
  • pattern_count() - identical to Pattern.count()
  • pattern_split() - identical to Pattern.split()
  • pattern_cut() - identical to Pattern.cut()
  • pattern_filter() - identical to Pattern.filter()
  • pattern_reject() - identical to Pattern.reject()

Functions which aren't directly present in core library, but can be easily simulated.

  • pattern_match_optional() - checks Matcher.test(), then returns either Matcher.first() or null
  • pattern_match_ref() - checks Matcher.test(), then passes &$ref with Matcher.first() or null

Frequently asked questions

  • Why is pattern/functions a separate library, and not a part of core library

    • Most object-oriented projects develop their applications only using classes, which are not "polluted" by rouge functions in the global namespace. To add global functions to the project is not in our competence.

      However, some users actually prefer the simplified approach, and they should be able to easily start their project. Because of that pattern/functions is available.

  • Why functions pattern_replace() and pattern_replace_callback() are separate functions, instead of a single function with dynamic type check string and callable?

    • We decided to separate the functions, because certain PHP string are also callable (e.g. 'strlen', 'strtoupper', etc.).
  • Why isn't there pattern_quote()?

    • Using preg_quote() is a more procedural approach to building regular expressions. In T-Regx, the recommended approach is using Prepared patterns: Pattern::inject() and Pattern::template(). Additionally, preg_quote() doesn't quote all of the necessary characters, for example in comments and also whitespaces in /x mode.
  • Why I shouldn't use @ with pattern/functions?

    • Notation @ is supposed to suppress PHP warnings/errors/notices, but T-Regx library doesn't issue warnings, errors and notices, so @ is redundant. Both core library and pattern/functions only throw exceptions, so try/catch should be used.
  • Why isn't there pattern_last_error()?

    • Such function is not necessary, since all functions in pattern/functions as well as in core library throw suitable exceptions on error.
  • Should I choose core T-Regx library or pattern/functions?

    • Choose the interface works better for your project. Everything that can be done with pattern/functions can also be done with core library, and pattern/functions are really thin wrappers on the core library.
  • Can I do with pattern/functions everything I can do with core library?

  • How does performance pattern/functions relate to core library?

    • In case of a single call (for example comparing pattern_test() and Pattern.test()) there is no difference in performance.
    • In case of repeated calls with the same pattern, then the core library approach is technically more performant, because of reused compiled pattern; however the difference can only be shown with millions of repeated matches.
  • How does T-Regx library prevent fatal errors?

    • Certain input values cause PHP and PCRE to fatally end and terminate the PHP process (for example, returning a non-stringable object from preg_replace_callback() terminates the application). T-Regx handles that by utilizing a careful if-ology, and when potentially dangerous value is returned, an exception is thrown instead.

Comparison against preg_ functions

  • pattern_ functions accept an undelimited regular expression, while preg_ functions argument must be delimited.
  • pattern_test() returns true/false, while preg_match() returns 0/1.
  • pattern_ functions handle errors with exceptions, while preg_ functions use warnings, notices, errors, fatal errors and error codes with preg_last_error().
  • pattern_ functions exposes details as Detail interface, while preg_ returns nested arrays.
  • pattern_match_all() returns an array of Detail objects, while preg_match_all() populates (string|int)[][] via &$ref.

Sponsors

T-Regx is developed thanks to

JetBrains

Our other tools

  • phpunit-data-provider

License

T-Regx is MIT licensed.

About

Helper functions for the T-Regx library

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Languages