diff --git a/readme.md b/readme.md index 2ce857b..2191367 100644 --- a/readme.md +++ b/readme.md @@ -221,6 +221,16 @@ Ranges of numbers are specified using a combination of `min()` and `max()`: $schema = Expect::int()->min(10)->max(20); ``` +Regular expressions +------------------- + +String can be restricted by regular expression using the `pattern()`: + +```php +// just 9 numbers +$schema = Expect::string()->pattern('\d{9}'); +``` + Data mapping to objects ----------------------- diff --git a/src/Schema/Elements/Type.php b/src/Schema/Elements/Type.php index 7f302b9..724fca3 100644 --- a/src/Schema/Elements/Type.php +++ b/src/Schema/Elements/Type.php @@ -30,6 +30,9 @@ final class Type implements Schema /** @var array */ private $range = [null, null]; + /** @var string|null */ + private $pattern; + public function __construct(string $type) { @@ -77,6 +80,13 @@ public function items($type = 'mixed'): self } + public function pattern(string $pattern): self + { + $this->pattern = $pattern; + return $this; + } + + /********************* processing ****************d*g**/ @@ -129,6 +139,10 @@ public function complete($value, Context $context) if (!$this->doValidate($value, $expected, $context)) { return; } + if ($this->pattern !== null && !preg_match("\x01^(?:$this->pattern)\\z\x01u", $value)) { + $context->addError("The option %path% expects to match pattern '$this->pattern', '$value' given."); + return; + } if ($value instanceof DynamicParameter) { $context->dynamics[] = [$value, str_replace('|' . DynamicParameter::class, '', $expected)]; diff --git a/tests/Schema/Expect.pattern.phpt b/tests/Schema/Expect.pattern.phpt new file mode 100644 index 0000000..cd802e6 --- /dev/null +++ b/tests/Schema/Expect.pattern.phpt @@ -0,0 +1,26 @@ +pattern('\d{9}'); + + Assert::same('123456789', (new Processor)->process($schema, '123456789')); +}); + + +test(function () { + $schema = Expect::string()->pattern('\d{9}'); + + checkValidationErrors(function () use ($schema) { + (new Processor)->process($schema, '123'); + }, ["The option expects to match pattern '\\d{9}', '123' given."]); +});