2012-06-26 2 views
2

У меня есть массив шаблонов:preg_match показать первый матч в цикле Еогеаспа

$patterns= array(
    '#http://(www\.)?domain-1.com/.*#i', 
    '#http://(www\.)?domain-2.com/.*#i', 
    ... 
); 

и у меня есть длинная строка, которая содержит несколько текста и ссылки, я хочу, чтобы соответствовать первому URL произошло в строке, я только попытался это:

foreach ($patterns as $pattern) { 
    preg_match($pattern, $the_string, $match); 
    echo '<pre>'; print_r($match); echo '</pre>'; 
} 

возвращает пустые массивы, где не подходят для некоторых моделей и массивов, который содержит URL-адрес, но в зависимости от того массива $patterns,

Как я могу найти совпадение этих шаблонов, которые произошли в первую очередь.

+0

Можете ли вы показать нам пример URL-адреса, который вы пытаетесь сопоставить, и образец шаблона? Проблема может заключаться в вашем шаблоне регулярного выражения, а не в вашем PHP. –

ответ

5

Вы в основном есть три варианты:

  1. соответствуют general URL pattern, а затем запустите этот URL против шаблонов, которые у вас есть. Если ни один из них не соответствует, продолжите второй результат из общего шаблона.
  2. запустите все ваши шаблоны с флагом PREG_OFFSET_CAPTURE, чтобы получить смещение, сопоставленное с рисунком. найдите самое низкое смещение, верните свой результат
  3. объедините свои различные узоры в один узор. Имейте в виду, что существуют ограничения на длину шаблона (64K in compiled form)

Вариант 2:

<?php 

$text = "hello world http://www.domain-2.com/foo comes before http://www.domain-1.com/bar"; 
$patterns= array(
    '#http://(www\.)?domain-1.com/[^\s]*#i', 
    '#http://(www\.)?domain-2.com/[^\s]*#i', 
); 

$match = null; 
$offset = null; 
foreach ($patterns as $pattern) { 
    if (preg_match($pattern, $text, $matches, PREG_OFFSET_CAPTURE)) { 
     if ($matches[0][1] < $offset || $offset === null) { 
      $offset = $matches[0][1]; 
      $match = $matches[0][0]; 
     } 
    } 
} 

var_dump($match); 

остерегайтесь, что я изменил свои демонстрационные образцы. Я заменил .* (ничего) на [^\s]* (все, кроме места), чтобы предотвратить совпадение шаблона больше, чем предполагалось

2

Я предполагаю, что вы ищете это:

foreach ($patterns as $pattern) { 
    if (preg_match($pattern, $the_string, $match)) { 
     echo '<pre>'; print_r($match); echo '</pre>'; 
     break; 
    } 
} 

UPDATE:

Тогда я думаю, вы должны работать со смещениями Линке это:

$matches = array(); 
foreach ($patterns as $pattern) { 
    if (preg_match($pattern, $the_string, $match, PREG_OFFSET_CAPTURE)) { 
     $matches[$match[0][1]] = $match[0][0]; 
    } 
} 
echo reset($matches); 
+0

Вы набрали его быстрее, чем я. :) – JROB

+0

Я не пытаюсь остановить после первого совпадения, это вернет совпадение, даже если оно находится в конце строки, но его шаблон находится в начале массива. – Pierre

+0

@Peter Я обновил свой ответ. Надеюсь, это сработает для вас. – flec

1

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

$easliestPos = strlen($the_string) + 1; 
$earliestMatch = false; 

foreach ($patterns as $pattern) { 
    if (preg_match($pattern, $the_string, $match)) { 
     $myMatch = $match[0]; 
     $myMatchPos = strpos($myMatch, $the_string); 
     if ($myMatchPos < $easliestPos) { 
      $easliestPos = $myMatchPos; 
      $earliestMatch = $myMatch ; 
     } 
    } 
} 

if ($earliestMatch) { 
    echo $earliestMatch; 
} 
Смежные вопросы