PCRE wrapping library that offers type-safe preg_* replacements.

Related tags

Strings pcre
Overview

composer/pcre

PCRE wrapping library that offers type-safe preg_* replacements.

If you are using a modern PHP version you are probably better off using spatie/regex instead as it offers more functionality.

This library is a minimalistic way to ensure preg_* functions do not fail silently, returning unexpected nulls.

Continuous Integration

Installation

Install the latest version with:

$ composer require composer/pcre

Requirements

  • PHP 5.3.2 is required but using the latest version of PHP is highly recommended.

Basic usage

Instead of:

if (preg_match('{fo+}', $string, $matches)) { ... }
if (preg_match_all('{fo+}', $string, $matches)) { ... }
$newString = preg_replace('{fo+}', 'bar', $string);
$newString = preg_replace_callback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);

You can now call these on the Preg class:

use Composer\Pcre\Preg;

if (Preg::match('{fo+}', $string, $matches)) { ... }
if (Preg::matchAll('{fo+}', $string, $matches)) { ... }
$newString = Preg::replace('{fo+}', 'bar', $string);
$newString = Preg::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);

The main difference is if anything fails to match/replace, it will throw a Composer\Pcre\PcreException instead of returning null, so you can now use the return values safely relying on the fact that they can only be strings (for replace) and ints (for match).

If you would prefer a slightly more verbose usage, replacing by-ref arguments by result objects, you can use the Regex class:

use Composer\Pcre\Regex;

$result = Regex::match('{fo+}', $string);
if ($result->matched) { something($result->matches); }

$result = Regex::matchAll('{fo+}', $string);
if ($result->matched && $result->count > 3) { something($result->matches); }

$newString = Regex::replace('{fo+}', 'bar', $string)->result;
$newString = Regex::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string)->result;

See the *Result classes for more.

License

composer/pcre is licensed under the MIT License, see the LICENSE file for details.

Comments
  • Add more preg wrapper methods

    Add more preg wrapper methods

    I appreciate that you are already working on this, but since I was already testing various API ideas it seemed quicker to knock up a POC to show how this library could provide safe wrappers for the full range of preg_* function usage (plus its own API), rather than discussing it all. So no worries if you don't want this.

    • Union types in the preg_* functions are supported (even though Composer may not use them itself)
    • The $subject param from PcreException::fromFunction has been removed because it was not used
    • ReplaceResult::result is now a string|string[]
    • Regex::isMatch has been introduced as syntax sugar for Regex::match(...)->matched

    Tests are needed for:

    • Preg::filter
    • Preg::grep
    • Preg::replaceCallbackArray
    • Preg::split

    There is an inconsistency between the preg_ functions that emit warnings (in that Preg::filter is the only one to suppress them) because I don't know what is best to do.

    opened by johnstevenson 12
  • Simplify matching: Match first / match firstOf

    Simplify matching: Match first / match firstOf

    Hi,

    thank you for the package, this is what I was looking for (I do like that you are using "result" objects).

    • Anyway I often need to match first group or - matchFirst
    • Also sometimes I need to try multiple regexes on the subject - matchFirstOf

    Checklist

    • [X] PHP CS Fixer
    • [X] Add tests
    • [X] PHPStan
    • [X] Explanation in commit messages (long message)
    • [ ] Documentation

    Are you OK with the changes?

    Thank you,

    FYI

    PHPStan

    There are 2 phpstan errors. Not sure how to fix it (I used PHP 8.1).

    > phpstan analyse
    Note: Using configuration file /Users/pion/Work/OpenSource/pcre/phpstan.neon.dist.
      0/33 [░░░░░░░░░░░░░░░░░░░░░░░░░░░░]   0% 33/33 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100%
    
     ------ ---------------------------------------------------------------------- 
      Line   src/Preg.php                                                          
     ------ ---------------------------------------------------------------------- 
      78     Strict comparison using === between int<0, max> and null will always  
             evaluate to false.                                                    
      98     Strict comparison using === between int<0, max> and null will always  
             evaluate to false.                                                    
     ------ ---------------------------------------------------------------------- 
    
    
     [ERROR] Found 2 errors        
    

    Linting

    In contribution we are instructed to use PHP CS fixer. Maybe would be great to require as dev dependency and add config + composer script? (I personally use ECS package

    opened by pionl 8
  • Initial API thoughts

    Initial API thoughts

    This is going to be a very useful library. And because it's in the Composer family it will likely become huge and invoke all sorts of feaure requests.

    In my view it primarily needs to be a drop-in replacement to make existing code safe. Using some Composer examples we can see how painless this could be:

    <?php
        if (preg_match($pattern, $line)) { ... }
        if (Regex::match($pattern, $line, $unused)) { ... }
    
        if (preg_match_all('{'.self::$DEFINES.'"'.$keyRegex.'"\s*:\s*(?:(?&json))}x', $children, $matches)) { ... }
        if (Regex::matchAll('{'.self::$DEFINES.'"'.$keyRegex.'"\s*:\s*(?:(?&json))}x', $children, $matches)) { ... }
    
        $childrenClean = preg_replace('{,\s*'.preg_quote($bestMatch).'}i', '', $children, -1, $count);
        $childrenClean = Regex::replace('{,\s*'.preg_quote($bestMatch).'}i', '', $children, -1, $count);
    

    We can cover everyone's needs with Regex::filter, Regex::grep, Regex::match, Regex::matchAll, Regex::replace, Regex::replaceCallback and Regex::replaceCallbackArray in not much code that wraps the native PHP functions and throws a nice PcreException on regex errors, without emitting any warnings. The only downside for users would be having to add the optional params if they are not being used.

    The decorator methods that return result objects could be simply named by appending Ex:

    <?php
    $result = Regex::matchEx('{fo+}', $string);
    if ($result->matched) { something($result->matches); }
    

    What do you think? (I can PR any of this you like, if you don't have the time).

    opened by johnstevenson 7
  • [2.x/3.x] Add matchNotNull and other *NotNull implementations

    [2.x/3.x] Add matchNotNull and other *NotNull implementations

    I'd be happy for a sanity check here before proceeding and adding the rest of them (matchWithOffsetsNotNull, matchAllNotNull, matchAllWithOffsetsNotNull, replaceCallbackNotNull, replaceCallbackArrayNotNull, isMatchNotNull, isMatchAllNotNull, isMatchWithOffsetsNotNull, isMatchAllWithOffsetsNotNull 😅 ).

    The issue is that due to the improvements in PHPStan and https://github.com/composer/pcre/releases/tag/3.0.2 you now get errors everywhere because $match[1] for ex is string|null even tho in many cases the null will never happen. This is however dependent on the pattern and thus cannot really be asserted easily in the types.

    So adding these NotNull variants for all functions outputting nullable matches solves this by letting you opt in to stricter non-nullable types, and if you messed up and your pattern does have null/unmatched-subpatterns you get an exception.

    The main problems I see and where I'd love feedback are:

    • is the NotNull name clear/confusing?
    • is it polluting the interface too much? It adds lots of "duplicate" methods but they are technically different and kinda similar to the WithOffset ones we already have. This makes me think perhaps the name should be WithoutNull tho.

    /cc @johnstevenson @naderman @stof

    enhancement 
    opened by Seldaek 5
  • Add Preg::isMatch and Preg::isMatchAll

    Add Preg::isMatch and Preg::isMatchAll

    More syntax sugar, returning bool from preg_match and preg_match_all whilst allowing the use of all parameters. These methods make the Preg class a complete drop-in replacement for the native functions.

    What do you think?

    opened by johnstevenson 2
  • Fix PHP 7.2/7.3 handling of PREG_UNMATCHED_AS_NULL

    Fix PHP 7.2/7.3 handling of PREG_UNMATCHED_AS_NULL

    This is a workaround for the discrepancy between 7.2/7.3 and above versions (https://3v4l.org/eU2di) using something along the lines of https://3v4l.org/D1vN2

    /cc @johnstevenson FYI because it's a fun one 🙈

    opened by Seldaek 1
Releases(3.1.0)
  • 3.1.0(Nov 17, 2022)

    What's Changed

    • Add matchStrictGroups and other strict group operations to avoid nullable matches by @Seldaek in https://github.com/composer/pcre/pull/14
    • Add replaceCallbackStrictGroups by @Seldaek in https://github.com/composer/pcre/pull/15

    Full Changelog: https://github.com/composer/pcre/compare/3.0.2...3.1.0

    Source code(tar.gz)
    Source code(zip)
  • 2.1.0(Nov 17, 2022)

    What's Changed

    • Add matchStrictGroups and other strict group operations to avoid nullable matches by @Seldaek in https://github.com/composer/pcre/pull/14
    • Fix PHP 7.2/7.3 handling of PREG_UNMATCHED_AS_NULL by @Seldaek in https://github.com/composer/pcre/pull/16

    Full Changelog: https://github.com/composer/pcre/compare/2.0.2...2.1.0

    Source code(tar.gz)
    Source code(zip)
  • 3.0.2(Nov 3, 2022)

    • Improved type annotations for static analysis, $matches will now be populated correctly with @param-out annotations (requires PHPStan 1.9)

    Full Changelog: https://github.com/composer/pcre/compare/3.0.1...3.0.2

    Source code(tar.gz)
    Source code(zip)
  • 3.0.1(Nov 3, 2022)

    What's Changed

    • Code cleanup by @pionl in https://github.com/composer/pcre/pull/13
    • Improved type annotations for static analysis

    Full Changelog: https://github.com/composer/pcre/compare/3.0.0...3.0.1

    Source code(tar.gz)
    Source code(zip)
  • 2.0.2(Nov 3, 2022)

    • Improved type annotations for static analysis, $matches will now be populated correctly with @param-out annotations (requires PHPStan 1.9)

    Full Changelog: https://github.com/composer/pcre/compare/2.0.1...2.0.2

    Source code(tar.gz)
    Source code(zip)
  • 2.0.1(Nov 3, 2022)

    What's Changed

    • Code cleanup by @pionl in https://github.com/composer/pcre/pull/13
    • Improved type annotations for static analysis

    New Contributors

    • @pionl made their first contribution in https://github.com/composer/pcre/pull/13

    Full Changelog: https://github.com/composer/pcre/compare/2.0.0...2.0.1

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Feb 25, 2022)

  • 2.0.0(Feb 25, 2022)

  • 1.0.1(Jan 21, 2022)

  • 1.0.0(Dec 6, 2021)

Owner
Composer
Composer
Enables type-safe comparisons of objects in PHPUnit.

Strict PHPUnit Enables type-safe comparisons of objects in PHPUnit. Problem PHPUnit has a very powerful comparison system that helps you comparing obj

Webmozarts GmbH 17 Aug 29, 2022
A PHP library for generating universally unique identifiers (UUIDs).

ramsey/uuid A PHP library for generating and working with UUIDs. ramsey/uuid is a PHP library for generating and working with universally unique ident

Ben Ramsey 11.9k Jan 8, 2023
A PHP string manipulation library with multibyte support

A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM. s('string')->toTitleCase()->ensureRight('y') ==

Daniel St. Jules 2.5k Jan 3, 2023
The Universal Device Detection library will parse any User Agent and detect the browser, operating system, device used (desktop, tablet, mobile, tv, cars, console, etc.), brand and model.

DeviceDetector Code Status Description The Universal Device Detection library that parses User Agents and detects devices (desktop, tablet, mobile, tv

Matomo Analytics 2.4k Jan 5, 2023
A fast PHP slug generator and transliteration library that converts non-ascii characters for use in URLs.

URLify for PHP A fast PHP slug generator and transliteration library, started as a PHP port of URLify.js from the Django project. Handles symbols from

Aband*nthecar 667 Dec 20, 2022
🉑 Portable UTF-8 library - performance optimized (unicode) string functions for php.

?? Portable UTF-8 Description It is written in PHP (PHP 7+) and can work without "mbstring", "iconv" or any other extra encoding php-extension on your

Lars Moelleken 474 Dec 22, 2022
ColorJizz is a PHP library for manipulating and converting colors.

#Getting started: ColorJizz-PHP uses the PSR-0 standards for namespaces, so there should be no trouble using with frameworks like Symfony 2. ###Autolo

Mikeemoo 281 Nov 25, 2022
🔡 Portable ASCII library - performance optimized (ascii) string functions for php.

?? Portable ASCII Description It is written in PHP (PHP 7+) and can work without "mbstring", "iconv" or any other extra encoding php-extension on your

Lars Moelleken 380 Jan 6, 2023
Library for free use Google Translator. With attempts connecting on failure and array support.

GoogleTranslateForFree Packagist: https://packagist.org/packages/dejurin/php-google-translate-for-free Library for free use Google Translator. With at

Yurii De 122 Dec 23, 2022
PHP library to parse urls from string input

Url highlight - PHP library to parse URLs from string input. Works with complex URLs, edge cases and encoded input. Features: Replace URLs in string b

Volodymyr Stelmakh 77 Sep 16, 2022
Text - Simple 1 Class Text Manipulation Library

Text - Simple 1 Class Text Manipulation Library Do you remember PHP's string functions? If not, just wrap you text with Text! It will save a minute on

Kazuyuki Hayashi 51 Nov 16, 2021
The Hoa\Ustring library.

Hoa is a modular, extensible and structured set of PHP libraries. Moreover, Hoa aims at being a bridge between industrial and research worlds. Hoa\Ust

Hoa 402 Jan 4, 2023
:accept: Stringy - A PHP string manipulation library with multibyte support, performance optimized

?? Stringy A PHP string manipulation library with multibyte support. Compatible with PHP 7+ 100% compatible with the original "Stringy" library, but t

Lars Moelleken 144 Dec 12, 2022
A language detection library for PHP. Detects the language from a given text string.

language-detection Build Status Code Coverage Version Total Downloads Minimum PHP Version License This library can detect the language of a given text

Patrick Schur 738 Dec 28, 2022
A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM.

A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM. s('string')->toTitleCase()->ensureRight('y') ==

Daniel St. Jules 2.5k Dec 28, 2022
PHP library to detect and manipulate indentation of strings and files

indentation PHP library to detect and manipulate the indentation of files and strings Installation composer require --dev colinodell/indentation Usage

Colin O'Dell 34 Nov 28, 2022
A sane interface for php's built in preg_* functions

Making regex great again Php's built in preg_* functions require some odd patterns like passing variables by reference and treating false or null valu

Spatie 1.1k Jan 4, 2023
A PHP webpage that uses string replacements to generate a binary on the fly that you can enter at setup in NEOS.

openpilot-installer-generator A PHP webpage that uses string replacements to generate a binary on the fly that you can enter at setup in NEOS. What is

null 34 Nov 17, 2022
Enables type-safe comparisons of objects in PHPUnit.

Strict PHPUnit Enables type-safe comparisons of objects in PHPUnit. Problem PHPUnit has a very powerful comparison system that helps you comparing obj

Webmozarts GmbH 17 Aug 29, 2022
A simple, type-safe, zero dependency port of the javascript fetch WebApi for PHP.

A simple, type-safe, zero dependency port of the javascript fetch WebApi for PHP.

Matias Navarro Carter 105 Jan 4, 2023