Два последовательных preg_match - PullRequest
1 голос
/ 08 февраля 2011

Я пытаюсь использовать два preg_match, чтобы получить два конкретных значения из исходного кода html.

<?php

    $url = "http://www.example.com";
    $userAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1";
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_USERAGENT,$userAgent);
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_AUTOREFERER,true);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_TIMEOUT,10000000);  
    $html  = curl_exec($ch);
    preg_match('~<span class="first">(.*)<\/span>~msU',$html,$matching_data);
    preg_match('~<span class="second">(.*)<\/span>~msU',$html,$matching_data2);
    print_r($matching_data);
    print_r($matching_data2);   
?>

Учитывая, что переменная $html содержит следующую последовательность:

<title>foobar title</title>
<body>
<div class="second">Not this one</span>
<div>
<span class="first">First</span>
<span class="second">this one<span>
</div>
</body>

Если я запускаю свой код php, первый print_r возвращает правильное значение: <span class="first">First</span>.Но вторая print_r вместо возврата <span class="second">this one<span> возвращает <div class="second">Not this one</span>.

Так что я предполагаю, что функция preg_match начинает обработку с начала, а не с последнего вызова preg_match.

Как я могу сделать второй (третий, четвертый и т. Д.) Вызов preg_match, выполняемый при последнем вызове?

Спасибо,

С уважением.

Ответы [ 3 ]

3 голосов
/ 08 февраля 2011

Чтобы сделать последовательные звонки на preg_match, продолжая поиск там, где вы остановились в последний раз, используйте флаг PREG_OFFSET_CAPTURE:

http://php.net/manual/en/function.preg-match.php

Что касается более крупной проблемы,регулярные выражения обычно не подходят для анализа HTML.Вы должны использовать какой-то DOM-парсер, чтобы выполнить эту работу за вас, и это, если вам даже нужно выполнить работу на стороне сервера.Подобные вещи могут быть выполнены чрезвычайно просто (и естественно) на стороне клиента с помощью JavaScript - вам просто нужно будет передать соответствующие значения обратно на сервер.

0 голосов
/ 08 февраля 2011

Это HTML код, с которым вам нужно работать?Это не правильный HTML.Вы можете использовать preg_match_all, как предложено @igorw:

preg_match_all('~<(span|div) class="(first|second)">(.*)<\/?span>~msU', $html,$matching_data);
echo '<xmp>'; print_r($matching_data[0]);

Но если HTML-код действителен:

<title>foobar title</title>
<body>
<span class="second">Not this one</span>
<div>
<span class="first">First</span>
<span class="second">this one</span>
</div>
</body>

preg_match_all('~<span class="(first|second)">(.*)<\/span>~msU', $html, $matching_data);
echo '<xmp>'; print_r($matching_data[0]);
0 голосов
/ 08 февраля 2011

Вы можете использовать аргументы захвата и смещения в функции preg_match ( php: preg_match )

int preg_match ( string $pattern, string $subject [, array &$matches[, int $flags [, int $offset]]] )

попробуйте это:

<?php

...

preg_match('~<span class="first">(.*)<\/span>~msU',$html,$matching_data,PREG_OFFSET_CAPTURE);
preg_match('~<span class="second">(.*)<\/span>~msU',$html,$matching_data2,PREG_OFFSET_CAPTURE, $matching_data[0][1]+strlen($matching_data[0][0]));
print_r($matching_data);
print_r($matching_data2); 
...