У меня есть массив, полный шаблонов, которые мне нужны. Любой способ сделать это, кроме цикла 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 } }