PHP: Как использовать in_array с массивом строк регулярных выражений? - PullRequest
1 голос
/ 21 мая 2019

У меня есть массив путей, состоящий из строк регулярных выражений:

  $paths = [
    '/cars$',
    '.*\/cars$',
    '^cars\/.*/',
    '/trucks$',
    '.*\/trucks$',
  ];

Я хочу проверить, соответствует ли мой текущий путь чему-либо в этом массиве, например:

if (in_array($current_path, $paths)) {
  //Do something
}

Итакнапример, если мой URL-адрес some-site.com/cars или some-site.com/cars/honda, я хочу вернуть что-то в операторе if.

Но я не могу понять, как заставить это работать с регулярным выражением.

Я исследовал, используя preg_grep(), но похоже, что он работает только с одним набором правил регулярных выражений одновременно.

Я могу заставить это работать с preg_match и строкой, например:

$paths = '/cars$|.*\/cars$|^cars\/.*/|/trucks$|.*\/trucks$';

if (preg_match($paths, $current_path)) {
  //Do something
}

Но со временем в этот список будет добавлено много URL-адресов, поэтому я бы предпочел использовать массив.

Кто-нибудь знает, есть ли функция, которая достигает этого?

Ответы [ 2 ]

3 голосов
/ 21 мая 2019

Если вы хотите знать, какие шаблоны массива соответствуют строке, как насчет использования array_filter .

$res = array_filter($paths, function ($v) USE ($url) {
  return preg_match('~'.$v.'~', $url);
});

См. Демонстрацию PHP на 3v4l.org

echo count($res)." patterns matched:\n"; print_r($res);

2 сопоставленных шаблона: Массив ([0] => / cars $ 1 =>. * / Cars $)

Используется ~ в качестве разделителя шаблонов, поэтому вам не нужно избегать всех этих слэшей URL.

Имейте в виду, что .*/cars$ выглядит избыточно, если вы уже соответствуете /cars$.


Если вы хотите разбить первый матч, используйте foreach, который, вероятно, более эффективен ( demo ).

foreach($paths AS $v) {
  if (preg_match('~'.$v.'~', $url)) {
    echo $v.' matched'; break;
  }
}

Вы также можете легко отобразить соответствующую часть из $url, используя $out из preg_match.

1 голос
/ 21 мая 2019

Я подумал, что могу использовать implode (), чтобы вернуть его в строку, например:

$paths = [
    '/cars$',
    '.*\/cars$',
    '^cars\/.*/',
    '/trucks$',
    '.*\/trucks$',
 ];

$paths_string = implode('|', $paths);

if (preg_match($paths_string, $current_path)) {
  //Do something
}
...