Как вы выполняете preg_match, где шаблон является массивом, в php?

У меня есть массив, полный шаблонов, которые мне нужны. Любой способ сделать это, кроме цикла for ()? Я пытаюсь сделать это наименее интенсивно, потому что я буду делать десятки из них каждую минуту.

Реальный пример мира: Im строит проверку статуса ссылки, которая проверяет ссылки на различные онлайн-видео-сайты, чтобы убедиться, что видео все еще живы. В каждом домене есть несколько «мертвых ключевых слов», если они найдены в html страницы, что означает, что файл был удален. Они хранятся в массиве. Мне нужно сопоставить содержимое pf с массивом, с выходом html страницы.

Прежде всего, если вы в буквальном смысле делаете только десятки раз в минуту , я бы не стал беспокоиться о производительности в этом случае. Эти совпадения довольно быстрые, и я не думаю, что у вас будет проблема с производительностью, итерация через массив шаблонов и вызов preg_match отдельно:

$matches = false; foreach ($pattern_array as $pattern) { if (preg_match($pattern, $page)) { $matches = true; } } 

Вы действительно можете объединить все шаблоны в один, используя оператор or как это предлагают некоторые люди, но не просто ударяйте их вместе с | , Это сильно испортится, если какой-либо из ваших шаблонов содержит оператор или оператор.

Я бы рекомендовал по крайней мере группировать ваши шаблоны с помощью круглых скобок, например:

 foreach ($patterns as $pattern) { $grouped_patterns[] = "(" . $pattern . ")"; } $master_pattern = implode($grouped_patterns, "|"); 

Но … Я не уверен, что это быстрее. Что-то должно пересекать их, будь то preg_match или PHP. Если бы мне пришлось догадаться, я бы предположил, что индивидуальные матчи будут близки так же быстро и легко читать и поддерживать.

Наконец, если производительность – это то, что вы ищете здесь, я думаю, что самое главное – вытащить совпадения без регулярных выражений в простую проверку «строка содержит». Я бы предположил, что некоторые из ваших проверок должны быть простыми строковыми проверками, например, посмотреть, находится ли «Этот сайт закрыт» на странице.

Таким образом:

 foreach ($strings_to_match as $string_to_match) { if (strpos($page, $string_to_match) !== false)) { // etc. break; } } foreach ($pattern_array as $pattern) { if (preg_match($pattern, $page)) { // etc. break; } } 

и избегая как можно большего количества preg_match() , вероятно, будет вашим лучшим выигрышем. strpos() намного быстрее, чем preg_match() .

 // assuming you have something like this $patterns = array('a','b','\w'); // converts the array into a regex friendly or list $patterns_flattened = implode('|', $patterns); if ( preg_match('/'. $patterns_flattened .'/', $string, $matches) ) { } // PS: that's off the top of my head, I didn't check it in a code editor 

Если вы просто ищете наличие строки в другой строке, используйте strpos, поскольку она быстрее.

В противном случае вы можете просто перебирать массив шаблонов, каждый раз вызывая preg_match.

Если ваши шаблоны не содержат много пробелов, другой вариант заключается в том, чтобы избегать массивов и использовать модификатор /x . Теперь ваш список регулярных выражений будет выглядеть так:

 $regex = "/ pattern1| # search for occurences of 'pattern1' pa..ern2| # wildcard search for occurences of 'pa..ern2' pat[ ]tern| # search for 'pat tern', whitespace is escaped mypat # Note that the last pattern does NOT have a pipe char /x"; 

С модификатором /x пробелы полностью игнорируются, за исключением случаев, когда в классе символов или предшествует обратная косая черта. Также допускаются комментарии, подобные приведенным выше.

Это позволит избежать цикла через массив.

Если у вас есть куча шаблонов, то вы можете объединить их в одно регулярное выражение и сопоставить это. Нет необходимости в цикле.

Как насчет выполнения str_replace() в HTML, который вы используете с помощью вашего массива, а затем проверяете, совпадает ли исходный HTML с оригиналом? Это было бы очень быстро:

  $sites = array( 'you_tube' => array('dead', 'moved'), ... ); foreach ($sites as $site => $deadArray) { // get $html if ($html == str_replace($deadArray, '', $html)) { // video is live } }