Получить ТЕГ значение " внешний HTML


мне Нужно получить значение (или значения, если у вас больше одного) ТЕГ <link> HTML с другого сайта.

Попытка:

$url = 'http://localhost/teste/';
$content = trim(file_get_contents($url));
preg_match("/<link(.*?)>/i",$content,$return); 
var_dump($return);

Возвращение:

array (size=2)
  0 => string '<link rel="shortcut icon" href="http://localhost/teste/icon.png">' (length=77)
  1 => string ' rel="shortcut icon" href="http://localhost/teste/icon.png"' (length=71)

я Не знаю, если я оставил, конечно, хорошо, но я хочу, что вернусь следующим образом:

array (size=1)
  0 => 
    array (size=2)
      'rel' => string 'shortcut icon' (length=13)
      'href' => string 'http://localhost/teste/icon.png' (length=31)
 10
Author: tadeubarbosa, 2014-02-11

4 answers

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

/<link.*?href="(.*?)".*?>/i

Учитывая, что:

  • Учитывая рейтинг stack, как PHP и демонстрация использования preg_match(), модификатор g " не существует среди поддержанных Модификаторы PCRE, доступные.

  • Согласно спецификациям HTML и XHTML тег не имеет значения, только атрибуты, различаются, в основном, из-за закрытия тега.

  • Следует учитывать, что не всегда атрибут href желаемого будет иметь свое значение в той же позиции, даже если он был вам писать HTML-код. Поэтому внимание, что существует что-либо до и после изменения атрибута.

, Как использовать, чтобы захватить все значения, просто используйте preg_match_all().

[EDIT]

Как указывает @Sergio, с выпуском stack первоначальное решение, представленное выше, не применяется, тем не менее, объяснение, содержащейся в нем имеет большое значение, и только это остается.

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

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

  1. Сначала изменим Регулярное Выражение, чтобы найти все атрибуты.

  2. , таких, Как PHP, не захватывает "групп" автоматически, то есть, вы определяете что-то в плен, и он захватывает столько раз, сколько экземпляров этой модели существуют, их нужно отделить каждой пары ключ=значение.

    PHP делаете очень много форм и жизнеспособной альтернативой было бы удалить пробелы между парами ключ=значение, и использовать parse_str(). Но почему для этого нам понадобится ER, ведь str_replace() простой bagunçaria, например, rel, сделаем все по-ER.

  3. Мы должны перебирать массив, производимый preg_match_all(), это неизбежно, но как я буду с применением той же процедуры, с каждым элементом массива, сопоставляя их данные, в другой, я предпочитаю использовать array_map():

  4. Preg_split() делает обслуживание нее, но даже она, передав массив, это не входит в формат, который вы должны, принимая такие атрибуты, как содержание. Мы можем обойти с помощью array_chunk():

  5. , Но array_chunk() производит N массивов внутри, которые уже знали, что, в свою очередь, находится внутри другой. OMFG! Я не хочу перебирать все это! В этом случае трюк сенсационные это транспонирование матрицы, и для этого, вероятно, ответ практике наиболее хорошо проголосовали, что я когда-либо видел поставляются этой stack ОС на английском языке.

, Когда пересекает эту матрицу, она находится таким образом:

array (size=2)
  0 => 
    array (size=2)
      0 => string 'rel' (length=3)
      1 => string 'href' (length=4)
  1 => 
    array (size=2)
      0 => string 'shortcut icon' (length=13)
      1 => string 'http://localhost/teste/icon1.png' (length=32)

Структура такая, что array_combine() справится легко:

Полный код может быть скопирована и просматривать запущенные через ссылки.

 6
Author: Bruno Augusto, 2020-06-11 14:45:34

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

Существует пост относительно старый, но довольно известная– о том, почему не использовать регулярные выражения для разбора HTML. В основном, HTML-не является языком регулярно и, по определению, не может быть воспринята как выражение регулярный.

Http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html

Это, конечно, если мы говорим о ситуации, в которой вы можете перемещаться по DOM (HTML, как вы используете PHP, является недопустимым).

Мое решение, из этого следует следующим образом:

<?php
$html = trim(file_get_contents('http://localhost/teste/'));
$dom = new DOMDocument;
$dom->loadXML($html);
$links = $dom->getElementsByTagName('link');
foreach ($links as $link) {
    print_r($link->getAttributes());
}
 8
Author: Rodrigo Rigotti, 2014-02-11 19:42:15

, Вы могли бы использовать класс PHP Simple HTML DOM Parser имеет хорошую документацию,

 4
Author: Erlon Charles, 2014-02-11 19:47:02

Я рекомендую использовать PHP Simple HTML DOM Parser, это здорово и очень проста в использовании, я использую несколько сценариев для анализа HTML с других сайтов.

Очень хороший ответ от Bruno Augusto, только хочу дополнить его ответ и дать еще несколько деталей, которые считаю важными, которые будут учтены и приняты во внимание. Когда мне нужно проанализировать HTML-содержимое и использование регулярного выражения для этого, я стараюсь сделать код более полным, потому что HTML-это очень нерегулярные, атрибуты, не имеет определенный порядок, и, возможно, коды разрывы строк, я предлагаю использовать регулярное выражение более "полной", в вашем случае я бы использовал это регулярное выражение:

/<link.*?href=\"([^\"]*?)\".*?\/?>/si

В Основном, улучшения 2 замен:

1 - (.*?) , ([^\"]*?) как это правильно сделать, поскольку не существуют символы, ", если разделитель атрибут - ", то же самое, если бы это был символ '.

2 - > \/?>, так как может быть или не символ / перед символом <.

3 - /i /si, поскольку могут быть разрывы строк между атрибуты, ценности, etc... не всегда все теги HTML в веб-сайты, полностью встроенный, может быть, один кусок в одной строке, а другую часть на другую линию.

, Если вы используете регулярное выражение, первоначально предложенный Bruno Augusto, она не может найти определенные коды в теге ССЫЛКИ, если они с разрывами строк или, если у вас carectere / (штанга, которая представляет собой закрывающий тег), например:

$string = <<<EOF
<link
rel="shortcut icon"
href="http://localhost/teste/icon.png"
>
EOF;

if ( preg_match_all( '/<link.*?href="(.*?)".*?>/i', $string, $matches, PREG_SET_ORDER ) ) {
    var_dump( $matches );
    die();
} else {
    echo 'Nenhuma tag encontrada.';
    /* Esta parte será executada pois não serão encontrados tags, devido as quebras de linhas e adicionalmente também há a presença do caractere "/" (barra) do fechamento da tag LINK */
}

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

$string = <<<EOF
<link
rel="shortcut icon"
href="http://localhost/teste/icon.png"
>
EOF;

if ( preg_match_all( '/<link.*?href=\"([^\"]*?)\".*?\/?>/si', $string, $matches, PREG_SET_ORDER ) ) {
    /* Tags encontradas com sucesso */
    var_dump( $matches );
    die();
}
 3
Author: Humberto Castelo Branco, 2014-02-14 08:51:57