PHPackages                             nimayneb/yawl - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. nimayneb/yawl

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

nimayneb/yawl
=============

YAWL - Yet another wildcard library - Match pattern for strings with asterisk and query token

2.2.0(5y ago)291GPL-3.0PHPPHP ^7.4.0CI failing

Since Sep 29Pushed 5y ago2 watchersCompare

[ Source](https://github.com/nimayneb/yawl)[ Packagist](https://packagist.org/packages/nimayneb/yawl)[ RSS](/packages/nimayneb-yawl/feed)WikiDiscussions master Synced 2mo ago

READMEChangelog (5)Dependencies (4)Versions (8)Used By (1)

YAWL - Yet another wildcard library
===================================

[](#yawl---yet-another-wildcard-library)

[![Build Status](https://camo.githubusercontent.com/2f459e1580f2a1573e8f53231a6fe6fdcd8b666725060e260b7e646cf1f8dec4/68747470733a2f2f7472617669732d63692e6f72672f6e696d61796e65622f7961776c2e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/nimayneb/yawl)

This is a library with classes for any wildcard implementation that finds pattern with \* (asterisk) and ? (query) token.

Problem
-------

[](#problem)

Without regular expression extension (named `ext-pcre` - before PHP 5.3) you have no wildcard support within PHP.

See .

The known wildcard behavior (see [Wildcard character (@Wikipedia)](https://en.wikipedia.org/wiki/Wildcard_character)) is limited for a good implementation.

A small remedy?

We need a kind of "compiled" and "cached" pattern. The implementation of regular expression like `preg_match` has a huge performance. We lost these advantage as of PHP 7.0, because of just-in-time compiled pcre pattern!

Table of content
----------------

[](#table-of-content)

1. Benchmark
2. Wildcard variants
3. Possible valid pattern
4. Invalid pattern
5. Escaping
6. Repeating phrases
7. Caching
8. Wish list
9. Appendix

API:

1. [Matcher (for use of single calls)](Documentation/WildcardMatcher.md)
2. [Performer (for use of multiple calls)](Documentation/WildcardPerformer.md)
3. [Converter (for use of regular expression)](Documentation/WildcardConverter.md)

Benchmark
---------

[](#benchmark)

When we benchmark several methods to match a fitting phrase (1000 random strings), we have a good results without "regular expressions":

*Single Byte:*

BenchmarkTimeReferenceDifference`WildcardPerformer`0.00353789100 %-`preg_match`0.0122389871 %71 %`WildcardMatcher`0.0163528925 %78 %*Multi Byte (like Unicode):*

BenchmarkTimeReferenceDifference`WildcardPerformer`0.00660086100 %-`mb_ereg_match`0.0129048848 %48 %`WildcardMatcher`0.0325250660 %79 %Internal PHP functions comparison
---------------------------------

[](#internal-php-functions-comparison)

FunctionWildcardMatcherWildcardPerformerstrlen95 (-4)substr54 (-1)strpos51 (-4)chr22 (0)Conditions5713 (-44)Wildcard variants
-----------------

[](#wildcard-variants)

!= character== 1 character&gt;= 2 charactersToken000(invalid)001??... / ??...\*010?011\*\*100(empty string)101??\*\* (draft)110?\*111\*Possible valid pattern
----------------------

[](#possible-valid-pattern)

```
    ??      (2 characters)
    ???*  (2-3 characters)

```

Invalid pattern
---------------

[](#invalid-pattern)

```
    ***
    ?**
    ?*?
    *?

```

Escaping
--------

[](#escaping)

```
    \\
    \?
    \*

```

Please note of this escaping scenarios:

SubjectPatternExplanation`search\\*``*\\*`matches `search\ ` with wildcard, then matches escaped `*``search\\*``*\\\\*`matches `search` with wildcard, then matches escaped `\ `, then matches `*` with wildcard`search\\*``*\\\\\\*`matches `search` with wildcard, then matches escaped `\ `, then matches escaped `*``search\\*``*\\\\\\\\*`matches `search` with wildcard, then matches escaped `\ `, then not matches escaped `\ ` - ignore rest of `*`Further explanation:

programmaticinternalafter escaping`\\``\``\``\\\\``\\``\`Repeating phrases
-----------------

[](#repeating-phrases)

The asterisk (`*`) has a problem finding the right position. If several identical phrases can be found in a string, the search must take place in all positions to find the pattern.

```
 Search: *is?ue (where is "*is")
Subject: this is an asterisk issue
 Founds:   ^  ^          ^   ^

```

The simplest solution is to break down the pattern recursively, but it should be not recursively.

Caching
-------

[](#caching)

The regular expression extension has a caching and compiling strategy to improve performance. The second time the same pattern is called, a tremendous increase in performance is achieved.

To help us to improve also performance, we use a simple key-value caching.

```
    protected array $cachedResults = [];

    public function match(string $subject): bool
    {
        return $this->cachedResults[$subject] ?? $this->cachedResults[$subject] = $this->computePhrases($subject, 0);
    }

```

This is not a preferred solution.

Wish list
---------

[](#wish-list)

- Remove recursive call of `WildcardPerformer::computePhrases` (see [Wikipedia - Matching wildcards](https://en.wikipedia.org/wiki/Matching_wildcards))
- Remove of `StringFunctionMapper` (too slow)
- Combine Matcher and Performer (two advantages in one)
- Caching interface
- New pattern `??**` (0 or 2 characters) or `?????**` (0 or 5 characters)
- [Glob support](https://en.wikipedia.org/wiki/Glob_(programming))
    - Example: `[abcdef0123456789]`, `[0-9a-f]`, `[!a-z]`
    - Use in YAWL:
        - `[0-9a-f]?` (one times)
        - `[0-9a-f]?*` (zero or one times)
        - `[0-9a-f]*` (zero or N times)
        - `[0-9a-f]**` (one or N times)
        - `[0-9a-f]x` (one times then follows `x`)

Appendix
--------

[](#appendix)

Common Algorithms:

- [Wildcard matching algorithms by "Alessandro Cantatore"](http://xoomer.virgilio.it/acantato/dev/wildcard/wildmatch.html)

Non-recursive Algorithms:

- [Matching Wildcards: An Improved Algorithm for Big Data by "Kirk J. Krauss"](http://developforperformance.com/MatchingWildcards_AnImprovedAlgorithmForBigData.html)

Recursive Algorithms:

- [Compares a filename or pathname to a pattern by "Apple"](https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/fnmatch.c.auto.html)
- [Stackoverflow - Recursive solutions for glob pattern matching by "Siler"](https://stackoverflow.com/questions/30823596/recursive-solutions-for-glob-pattern-matching)

PDepend
-------

[](#pdepend)

[![Build Status](Resources/PDependPyramid.svg)](Resources/PDependPyramid.svg)

- NOP - Number Of Packages
- NOC - Number Of Classes
- NOM - Number Of Methods
- LOC – Lines of Code
- CYCLO - Cyclomatic complexity
- CALLS - number of distinct function- and method-calls
- ANDC - Average Number of Derived Classes
- AHH - Average Hierarchy Height

###  Health Score

27

—

LowBetter than 49% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~45 days

Recently: every ~56 days

Total

6

Last Release

2187d ago

Major Versions

1.1 → 2.0.02019-10-14

### Community

Maintainers

![](https://www.gravatar.com/avatar/0fbcb5c834ad511bbf12b303f38026f1c00466d4e2fe1e96f5bcfbae83779ac9?d=identicon)[nimayneb](/maintainers/nimayneb)

---

Top Contributors

[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")[![nimayneb](https://avatars.githubusercontent.com/u/9550921?v=4)](https://github.com/nimayneb "nimayneb (1 commits)")

---

Tags

stringtokenquerystringspatternMatchasteriskmatcherwildcardquestion markquestionmark

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/nimayneb-yawl/health.svg)

```
[![Health](https://phpackages.com/badges/nimayneb-yawl/health.svg)](https://phpackages.com/packages/nimayneb-yawl)
```

###  Alternatives

[doctrine/inflector

PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.

11.4k855.8M711](/packages/doctrine-inflector)[nette/utils

🛠 Nette Utils: lightweight utilities for string &amp; array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.

2.1k394.3M1.5k](/packages/nette-utils)[league/uri-components

URI components manipulation library

31932.3M66](/packages/league-uri-components)[opis/string

Multibyte strings as objects

7120.9M7](/packages/opis-string)[delight-im/str

Convenient object-oriented operations on strings

68336.2k2](/packages/delight-im-str)[ptrofimov/matchmaker

Ultra-fresh PHP matching functions

27167.7k](/packages/ptrofimov-matchmaker)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
