Fluent regular expressions in PHP

Related tags

Miscellaneous flux
Overview

FLUX (Fluent Regex) 0.5.2

Build Status Total Downloads Latest Stable Version

by Selvin Ortiz

Description

Fluent Regular Expressions in PHP inspired by and largely based on VerbalExpressions:JS by Jesse Luoto

@see inspiration & credits below for more info.

Requirements

  • PHP 5.3
  • Composer

Install

Flux is available as a package via composer

  • require: "selvinortiz/flux": "dev-master"
  • autoload: require_once 'path/to/vendor/autoload.php'
  • namespace: use SelvinOrtiz\Utils\Flux\Flux;
  • instantiate: $flux = Flux::getInstance();

You can additionally clone/download this repo and do whatever you want: )


@Example

This simple example illustrates the way you would use flux and it's fluent interface to build complex patterns.

require_once realpath(__DIR__.'/../vendor/autoload.php');

use SelvinOrtiz\Utils\Flux\Flux;
use SelvinOrtiz\Utils\Flux\Helper;

// The subject string (URL)
$str	= 'http://www.selvinortiz.com';

// Building the pattern (Fluently)
$flux	= Flux::getInstance()
		->startOfLine()
		->find('http')
		->maybe('s')
		->then('://')
		->maybe('www.')
		->anythingBut('.')
		->either('.co', '.com')
		->ignoreCase()
		->endOfLine();

// Output the Flux instance
Helper::dump( $flux );

// Output the fluently built pattern (@see /src/SelvinOrtiz/Utils/Flux/Helper)
Helper::msg( $flux ); // /^(http)(s)?(\:\/\/)(www\.)?([^\.]*)(.co|.com)$/i

// Inspect the results
Helper::msg( $str );
Helper::msg( $flux->match( $str ) ? 'matched' : 'unmatched' );
Helper::msg( $flux->replace( 'https://$5$6', $str ) );

For other examples, please see the /etc directory.


@Changelog


0.5.2

  • Adds length() method which adds or replaces the modifier used in the previous call
  • Adds getLastSegmentKey()
  • Adds the (empty) Factory class for optimized, often used patterns
  • Fixes indentation and EOF on phpunit.xml
  • Fixes comment typos on README and example files Pull Request #10

0.5.1

  • Adds getSegments() which was not included in 0.5.0 Issue #5
  • Adds removeSegment() which can be used in unit tests as well
  • Adds lineBreak() and br() which matches a new line (DOS/Unix)
  • Adds clear() which allows you to clear out the pattern and start from scratch
  • Adds getPattern() which compiles the expression and returns it
  • Adds `deprecation candidates as @todos
  • Fixes mixed logic between add() and raw()
  • Fixes implementation on the orTry() method
  • Moves example in readme above changelog
  • Improves unit tests

0.5.0 (Beta)

  • Adds getSegments() to improve testability Issue #5
  • Adds composer package selvinortiz/flux
  • Adds dev branch
  • Adds contributing notes
  • Adds install notes

0.4.5

  • Fixes internal namespace conflict
  • Changes namespace from Sortiz\Tools to SelvinOrtiz\Utils\Flux
  • Adds composer support Issue #3
  • Adds the addSeed() and removeSeed() methods Issue #4
  • Adds the getInstance() static method
  • Adds FluxUrlExample.php, FluxDateExample.php, and FluxPhoneExample.php
  • Adds getSeed() to get the seed without forcing __toString on the object
  • Adds getSegment() to extract a segment (capturing group) from the pattern
  • Implements unit tests (60% coverage) Issue #3
  • Implements Full PSR-2 Compliance (Tabs over Spaces)
  • Enables the seed on match() and replace() Issue #4
  • Removes example.php and defines them elsewhere
  • Moves examples into /etc and defines one example per file
  • Other small fixes and additions

0.4.0

  • Adds Flux to the Sortiz\Tools namespace
  • Implements PSR-2 Compliance (Tabs over Spaces)
  • Updates version number on Flux and this readme file
  • Updates the class instantiation with fully qualified class name on example.php
  • Adds references to other repos that have ported flux
  • Addresses concerns outlined in Issue #3

0.3.0

  • Improves documentation with phone/date examples
  • Adds the letters() method
  • Renames the numbers() method to digits()
  • Adds support for quantifiers for digits()
  • Adds ignoreCase() and promotes it above inAnyCase()
  • Improves the documented API

Thought hard about changing the name to FluentX any thoughts?


0.2.0

  • Adds the either( $option1, $option2 [, $option3 ...] ) method to handle OR cases
  • Updates the fluent example in this readme file
  • Adds the license

0.1.0 (Alpha)

Initial preview release


@Todo

  • Add source code comments
  • Add support for quantifiers
  • Add language methods for more advanced use cases
  • Add reference to repos that have ported Flux (*)
  • Add license notes (*)
  • Add contributing notes (*)
  • Add credits (*)

FLUX API

The flux API was designed to give you a fluent chainable object to build patterns with.

startOfLine()

Adds a beginning of line ^ modifier

endOfLine()

Adds an end of line $ modifier

find( $val ) & then( $val )

Allows you to augment the pattern with a required segment and it escapes regular expression characters

maybe( $val )

Allows you to augment the pattern with an optional segment

any( $val ) & anyOf( $val )

Allows you to create a set of characters to match

anything()

Adds a wild card (.*) segment to the pattern but it does not make dotAll() explicit

anythingBut( $val )

Will match anything but the characters in $val which is opposite of any() and anyOf

br() & lineBreak()

Allows you to match a new line (DOS/Unix)

tab()

Adds a (\t) to the pattern which will match a tab

word()

Adds (\w+) to the pattern which will match a single word

letters( $min=null, $max=null )

Only matches characters in the alphabet and uses $min and $max to create a quantifier

digits( $mix=null, $max=null )

Only matches digits and uses $min and $max to create a quantifier like word()

range( $from, $to [, $from, $to ...])

Allows you to create a range character class like a-z0-9 by calling range('a', 'z', 0, 9)

orTry( $val='' )

Allows you to create OR cases (this)|(else) and retain the capturing order to use in replace()

ignoreCase() & inAnyCase()

Adds the i modifier to the pattern which will allow you to match in a case insensitive manner

matchNewLine() & dotAll()

Adds the s modifier to the pattern which will allow you to match a new line when using anything()

multiline()

Adds the m modifier to the pattern which will allow you to search across multiple lines

oneLine() & searchOneLine()

Removes the modifier added by multiline() if it was previously called

match( $subject )

Simply takes your $subject in, compares it against the pattern, and returns whether a it matched or not

replace( $replacement, $subject )

You can replace matched segments by using the $x format where x is the (int) position of the matched segment

getPattern()

Returns the compiled pattern which you can also get by using the flux instance in a context where __toString() will be called

clear()

Clears the created pattern along with the modifiers, prefixes, and suffixes


Flux Elsewhere

There is a straight port of Flux for NodeJS by James Brooks whom has also collaborated on this project.

Feedback

This is something that started as a weekend experiment but I would love to take it further so if you have any suggestions, please fire away!

The best way to get in touch with me is via twitter @selvinortiz we'll take if from there :)

Contributing

  1. Check for open issues or open a new issue for a feature request or a bug
  2. Fork this repo to start making your changes to the dev branch or branch off
  3. Write a test which shows that the bug was fixed or that the feature works as expected
  4. Send a pull request and bug me until I merge it or tell you no cigar; )

Inspiration & Credits

This project is inspired and largely based on VerbalExpressions:JS by Jesse Luoto whom on July 20, 2013 started a weekend project that generated a lot of interest in the developer community and that project has proven to have a lot of potential.

Flux is not a straight port of VerbalExpressions but if you're interested in a straight VerbalExpressions port for PHP you should checkout VerbalExpressions:PHP by Mark Wilson

VerbalExpressions has also been ported to Ruby, Java, Groovy as of this update (July 25, 2013).

For a little background as to why flux was created and why you should use it, please refer to Issue #7 for a discussion on that matter.

MIT License

Flux is released under the MIT license which pretty much means you can do with it as you please and I won't get mad because I'm that nice; )

Comments
  • VerbalExpressions

    VerbalExpressions

    I think you should really credit this source properly, since this is apparently a port:

    https://github.com/jehna/VerbalExpressions

    Note that there's already a PHP port in that repo, although this one is much better :) And also there's this port:

    https://github.com/markwilson/VerbalExpressionsPhp

    Maybe you guys should get together and work on one definitive PHP version?

    opened by zeebinz 8
  • Node.js port

    Node.js port

    @selvinortiz, I've written a Node.js port of flux which you can install from the NPM registry here. Function names are the same, it's almost a straight port, only a few changes for using new RegExp, the tests pass though.

    I'll try and keep the port up to date with this repository and update the README later.

    opened by jbrooksuk 8
  • US Date example error?

    US Date example error?

    I don't know if my port has done something wrong here, but the example of US Date doesn't match my output.

    // Pattern /^(\()(\d{3})(\))( )?(\d{3})([ \-])(\d{4})$/
    echo $flux->match( $date ) ? 'matched' : 'unmatched'; // matched
    echo $flux->replace( '$3/$5/$7', $date ); // 612.424.0013
    

    Yet mine outputs:

    //Pattern (\w+)(, )([a-zA-Z]{3})( )(\d{1,2})(, )(\d{4})
    // matched
    // Jul/22/2013
    

    And here is the code:

    var USDate = new Flux();
    
    var testDate = 'Monday, Jul 22, 2013';
    USDate.startOfLine().word().then(', ').letters(3).then(' ').digits(1, 2).then(', ').digits(4).endOfLine();
    console.log(USDate.pattern.join(''));
    console.log(USDate.match(testDate) ? "matched" : "unmatched");
    console.log(USDate.replace('$3/$5/$7', testDate));
    

    Anything wrong there?

    I haven't tested your code as I don't have PHP setup here.

    opened by jbrooksuk 5
  • Consider droppping php-5.x supports

    Consider droppping php-5.x supports

    Since PHP 7.1 version is released and it's current PHP version.

    I think this should be considered.

    Once this issue is accepted, I would be happy to this :).

    opened by peter279k 3
  • digits 0 or more

    digits 0 or more

    I would like to find 0 or more digits, like so:

    $flux->digits(0, 10);
    

    however, the digits method will always fall to the else, as 0 is false and the condition states $min && $max see below:

    if ($min && $max)
    {
        return $this->raw(sprintf('(\\d{%d,%d})', $min, $max));
    }
    

    I may be misunderstanding how to achieve the 0 or more with the Flux library. However

    if (! is_null($min) && ! is_null($max))
    

    Would resolve the issue for my use case. What would you thoughts be on this?

    opened by apburton84 3
  • Zero sized ranges don't create valid patterns

    Zero sized ranges don't create valid patterns

    Hi,

    Thanks for lib, great. Slight issue

    ->letters(0,1)

    creates a pattern

    [a-zA-Z]+

    rather than

    [a-zA-Z]{0,1}

    Fix is to compare to null rather than if ($min) which fails if ZERO provided.

    Same in all other functions where min and max allowed.

    Matt

    public function letters($min = null, $max = null)
    {
    
        if (!is_null($min) && !is_null($max))
        {
            return $this->raw(sprintf('([a-zA-Z]{%d,%d})', $min, $max));
        }
        elseif (!is_null($min) && is_null($max))
        {
            return $this->raw(sprintf('([a-zA-Z]{%d})', $min));
        }
        else
        {
            return $this->raw('([a-zA-Z]+)');
        }
    }
    
    opened by roxburghm 3
  • removeSegment?

    removeSegment?

    Since you can getSegment, would it be worth being able to removeSegment? It'd only be used really when running tests or maybe changing your regex based on a later condition.

    opened by jbrooksuk 3
  • Maybe letters or digits

    Maybe letters or digits

    Is there currently functionality for this type of regular expression:

    ([A-Z]+)? 
    

    Something like:

    $flux->maybe($flux->letters());
    

    or

    $flux->maybeLetters();
    

    Any help in this regard would be greatly appreciated

    opened by apburton84 2
  • Fixed problem with zero min lengths being ignored

    Fixed problem with zero min lengths being ignored

    when $min was zero the code was assuming it hadn't been passed so it was impossible to have ranges "0-n" as they just became "n".

    Also added a test to validate it

    opened by roxburghm 2
  • PHPunit suite + travis as CI

    PHPunit suite + travis as CI

    I've added the phpunit as suite, and travis as the CI for the project, and updated the readme with some images that show the:

    • build status of travis
    • package downloads
    • package last stable version
    opened by krolow 2
  • Common Patterns

    Common Patterns

    It feels like based on the fluent interface we're building it would be a good idea to implement common patterns to make the API more fluent.

    Maybe methods such as:

    • ssn()
    • phrase()
    • password()
    • username()
    • creditCard()

    Thoughts?

    enhancement question 
    opened by selvinortiz 1
  • Negative look behind or not()

    Negative look behind or not()

    the implementation of:

    $flux->not('something');
    

    would be of great use to myself

    (?!something)
    

    An implementation of:

    public function not($string)
    {
        return $this->raw(sprintf('(?!%s)', $string));
    }
    
    opened by apburton84 1
Releases(v0.5.1)
  • v0.5.1(Jul 24, 2013)

    This is the initial stable release and my hope is that with your feedback, I'll be able to get this production ready withing the next week or two.

    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(Jul 23, 2013)

Owner
Selvin Ortiz
Culinary professional turned software developer. Building delightful tools at Kingdom Advisors, Inc. and leading an amazing team at Mod Creative, Inc.
Selvin Ortiz
πŸ¦‰ human-readable regular expressions for PHP

RegExpBuilder integrates regular expressions into the programming language, thereby making them easy to read and maintain. Regular Expressions are created by using chained methods and variables such as arrays or strings.

Max Girkens 907 Dec 30, 2022
YCOM Impersonate. Login as selected YCOM user πŸ§™β€β™‚οΈin frontend.

YCOM Impersonate Login as selected YCOM user in frontend. Features: Backend users with admin rights or YCOM[] rights, can be automatically logged in v

Friends Of REDAXO 17 Sep 12, 2022
Enable method chaining or fluent expressions for any value and method.

PHP Pipe Operator A (hopefully) temporary solution to implement the pipe operator in PHP. Table of contents Requirements How to install How to use The

Sebastiaan Luca 268 Dec 26, 2022
Best regular expression for gmail

best regular expression for gmail Gmail Regular expression with all details (not start with dot,number , is it possible to use multiple dot but not in

null 3 Feb 2, 2022
High performance view templating API for PHP applications using tags & expressions inspired by Java JSTL and C compiler

View Language API Table of contents: About Expressions Tags Configuration Compilation Installation Unit Tests Examples Reference Guide About This API

Lucian Gabriel Popescu 0 Jan 9, 2022
A simple, standalone, modern PHP class inspector and mapper library, wrapping PHPs native reflection in a fluent interface

A simple, standalone, modern PHP class inspector and mapper library, wrapping PHPs native reflection in a fluent interface.

smpl 9 Sep 1, 2022
Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

Introduction Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services. It handles almost all of the boilerpl

The Laravel Framework 2.2k Dec 31, 2022
The package provides an expressive "fluent" way to define model attributes.

The package provides an expressive "fluent" way to define model attributes. It automatically builds casts at the runtime and adds a native autocompletion to the models' properties.

Boris Lepikhin 506 Dec 28, 2022
Create executable strings using a fluent API.

command-builder A PHP class to build executable with using fluent API. Summary About Features Installation Examples Compatibility table Tests About I

Khalyomede 2 Jan 26, 2022
Strings Package provide a fluent, object-oriented interface for working with multibyte string

Strings Package provide a fluent, object-oriented interface for working with multibyte string, allowing you to chain multiple string operations together using a more readable syntax compared to traditional PHP strings functions.

Glowy PHP 14 Mar 12, 2022
A fluent interface for interacting with Netopia's services.

laravel-netopia A fluent interface for interacting with Netopia's services. Info Database It'll create a table named netopia_payments with the followi

Codestage 3 Oct 10, 2022
This package provides a simple and intuitive way to work on the Youtube Data API. It provides fluent interface to Youtube features.

Laravel Youtube Client This package provides a simple and intuitive way to work on the Youtube Data API. It provides fluent interface to Youtube featu

Tilson Mateus 6 May 31, 2023
The Current US Version of PHP-Nuke Evolution Xtreme v3.0.1b-beta often known as Nuke-Evolution Xtreme. This is a hardened version of PHP-Nuke and is secure and safe. We are currently porting Xtreme over to PHP 8.0.3

2021 Nightly Builds Repository PHP-Nuke Evolution Xtreme Developers TheGhost - Ernest Allen Buffington (Lead Developer) SeaBeast08 - Sebastian Scott B

Ernest Buffington 7 Aug 28, 2022
A sampling profiler for PHP written in PHP, which reads information about running PHP VM from outside of the process.

Reli Reli is a sampling profiler (or a VM state inspector) written in PHP. It can read information about running PHP script from outside of the proces

null 272 Dec 22, 2022
PHP Meminfo is a PHP extension that gives you insights on the PHP memory content

MEMINFO PHP Meminfo is a PHP extension that gives you insights on the PHP memory content. Its main goal is to help you understand memory leaks: by loo

Benoit Jacquemont 994 Dec 29, 2022
A sampling profiler for PHP written in PHP, which reads information about running PHP VM from outside of the process.

Reli Reli is a sampling profiler (or a VM state inspector) written in PHP. It can read information about running PHP script from outside of the proces

null 258 Sep 15, 2022
A multithreaded application server for PHP, written in PHP.

appserver.io, a PHP application server This is the main repository for the appserver.io project. What is appserver.io appserver.io is a multithreaded

appserver.io 951 Dec 25, 2022
Easy to use utility functions for everyday PHP projects. This is a port of the Lodash JS library to PHP

Lodash-PHP Lodash-PHP is a port of the Lodash JS library to PHP. It is a set of easy to use utility functions for everyday PHP projects. Lodash-PHP tr

Lodash PHP 474 Dec 31, 2022
A PHP 5.3+ and PHP 7.3 framework for OpenGraph Protocol

Opengraph Test with Atoum cd Opengraph/ curl -s https://getcomposer.org/installer | php php composer.phar install --dev ./vendor/atoum/atoum/bin/atoum

Axel Etcheverry 89 Dec 27, 2022