0

I have an array the elements of which are paths and contain forward slashes and exclamation marks.

And I need to inject such an array as regex pattern to preg_match()

$url = 'example.com/path/to/!another';
$arr = ['path/to/!page', 'path/to/!another'];
$unescapedPattern = implode('|', $arr);
$escapedPattern = preg_quote($unescapedPattern, '/');

if(preg_match('/('.$escapedPattern.')/', $url)) {
    echo 'The input url contains one of the paths in array!';
}

Of course the pattern is not applied because preg_quote() escapes the vertical bar

How to exclude it from escaping or how to resolve the issue another way?

stckvrw
  • 1,689
  • 18
  • 42
  • 2
    preg_quote() each item in the array before imploding. Or apply each pattern in the array in a loop. Or (possibly, depending on your needed characters) just use a character besides forward slash as your pattern delimiters. – Alex Howansky Nov 17 '22 at 22:06
  • If you just want to find a substring and don't need regex syntax, there's nothing wrong with looping over `$arr` and doing a `stripos($url, $value)` for every value in the array. That has the added advantage of being able to `break` once you found a match if you only need to find one in order to proceed. – oriberu Nov 17 '22 at 22:25
  • @stckvrw The regex engine is going to loop over the text for you quite excessively with an arbitrary amount of alternation. Just saying. ;) – oriberu Nov 17 '22 at 22:31
  • Use `$escapedPattern = implode("|", array_map(function($x) {return preg_quote($x, '/');}, $arr));`. The `$unescapedPattern = implode('|', $arr);` part can be removed. – Wiktor Stribiżew Nov 18 '22 at 00:08

1 Answers1

1

You can use

$url = 'example.com/path/to/!another';
$arr = ['path/to/!page', 'path/to/!another'];
$escapedPattern = implode("|", array_map(function($x) {return preg_quote($x, '/');}, $arr));

if(preg_match('/('.$escapedPattern.')/', $url)) {
    echo 'The input url contains one of the paths in array!';
}

Make sure you use the '/' as the second argument to preg_quote since you are using / as a regex delimiter char.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563