Regex, чтобы найти все URL и названия - PullRequest
4 голосов
/ 24 октября 2011

Я хотел бы извлечь все URL и заголовки из абзаца текста.

Les <a href="http://test.com/blop" class="c_link-blue">résultats du sondage</a> sur les remakes et suites souhaités sont <a href="http://test.com" class="c_link-blue">dans le blog</a>.

Я могу получить все href благодаря следующему регулярному выражению, но я не знаю, как дополнительно получить заголовок между <a></a> тэгами?

preg_match_all('/<a.*href="?([^" ]*)" /iU', $v['message'], $urls);

Лучше всего получить такой ассоциативный массив

[0] => Array
(
   [title] => XXX
   [link] => http://test.com/blop
)
[1] => Array
(
   [title] => XXX
   [link] => http://test.com
)

Спасибо за вашу помощь

Ответы [ 5 ]

3 голосов
/ 24 октября 2011

Как уже упоминалось в комментариях, используйте не регулярное выражение, а анализатор DOM.
Э.Г.

<?php
$doc = new DOMDocument;
$doc->loadhtml( getExampleData() );

$xpath = new DOMXPath($doc);
foreach( $xpath->query('/html/body/p[@id="abc"]//a') as $node ) {
    echo $node->getAttribute('href'), ' - ' , $node->textContent, "\n";
}

function getExampleData() {
    return '<html><head><title>...</title></head><body>
    <p>
        not <a href="wrong">this one</a> but ....
    </p>
    <p id="abc">
        Les <a href="http://test.com/blop" class="c_link-blue">résultats du sondage</a> sur les remakes et suites souhaités sont <a href="http://test.com" class="c_link-blue">dans le blog</a>.
    </p>
    </body></html>';
}

см. http://docs.php.net/DOMDocument и http://docs.php.net/DOMXPath

3 голосов
/ 24 октября 2011

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

<a.*?href="(.*?)".*?>(.*?)</a>

Обратите внимание, что он не использует модификатор U, как ваш.

Обновление: Чтобы он мог принимать одинарные кавычки, а также двойные кавычки, вместо этого можно использовать следующий шаблон:

<a.*?href=(?:"(.*?)"|'(.*?)').*?>(.*?)</a>
2 голосов
/ 24 октября 2011

Вы не должны использовать RegEx для этого.Вы должны использовать парсер XML / DOM.Я сделал это быстро, используя DOMDocument .

$links = array();
$dom = new DOMDocument;
@$dom->loadHTML('Les <a href="http://test.com/blop" class="c_link-blue">résultats du sondage</a> sur les remakes et suites souhaités sont <a href="http://test.com" class="c_link-blue">dans le blog</a>.');
$xPath = new DOMXPath($dom);
$a = $xPath->query('//a');
for($i=0; $i<$a->length; $i++){
    $e = $a->item($i);
    $links[] = array(
        'title' => $e->nodeValue,
        'link' => $e->getAttribute('href')
    );
}
print_r($links);

DEMO: http://codepad.org/2LEn2CAJ

1 голос
/ 24 октября 2011
preg_match_all("/<a[^>]*href=\"([^\"]*)[^>]*>([^<]*)</a>/", $v['message'], $urls, PREG_SET_ORDER)

должен работать, чтобы дать вам то, что вы хотите.Это не связанный массив, но это должен быть вложенный массив в нужном вам формате.

0 голосов
/ 24 октября 2011

Для людей, предлагающих использовать DOM, было бы неплохо использовать DOM.Но, конечно, вы не будете использовать парсер FULL DOM только для разбора пары URL / заголовков!

Просто используйте таким образом регулярное выражение:

/<a.*href="([^" ]*)".*>(.*)<\/a>/iU
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...