Почему это регулярное выражение возвращает ошибки, когда я использую его для поиска img src из HTML? - PullRequest
1 голос
/ 28 ноября 2008

Я пишу функцию, которая выискивает src из первого тега изображения, найденного в html-файле. Следуя инструкциям в этой теме здесь, я получил что-то, что, кажется, работает:

preg_match_all('#<img[^>]*>#i', $content, $match); 

foreach ($match as $value) {
    $img = $value[0];
                           } 

$stuff = simplexml_load_string($img);
$stuff = $stuff[src];
return $stuff;

Но после нескольких минут использования функции она стала возвращать ошибки, подобные этой:

предупреждение: simplexml_load_string () [0function.simplexml-load-string0]: объект: строка 1: ошибка синтаксического анализатора: преждевременное завершение данных в теге img строка 1 в пути / к / скрипту в строке 42.

и

предупреждение: simplexml_load_string () [0function.simplexml-load-string0]: tp: //feeds.feedburner.com/~f/ChicagobusinesscomBreakingNews? I = KiStN "border =" 0 "> в пути / к / сценарию в строка 42.

Я немного новичок в PHP, но, похоже, мое регулярное выражение неправильно обрабатывает HTML. Как я могу сделать его более "герметичным"?

Ответы [ 4 ]

2 голосов
/ 29 ноября 2008

Эти две строки кода PHP должны дать вам список всех значений атрибута src во всех тегах img в файле HTML:

preg_match_all('/<img\s+[^<>]*src=["\']?([^"\'<>\s]+)["\']?/i', $content, $result, PREG_PATTERN_ORDER);
$result = $result[1];

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

0 голосов
/ 28 ноября 2008

Амперсанд сам по себе в атрибуте является недопустимым XML (он должен быть закодирован как «& amp;»), но некоторые люди по-прежнему называют его таковым для URL на страницах HTML (и все браузеры поддерживают его). Может быть, в этом твоя проблема.

Если это так, вы можете очистить строку перед ее анализом, заменив «&(?!amp;)» на «&amp;».

0 голосов
/ 28 ноября 2008

На другую тему:

foreach ($match as $value) {
    $img = $value[0];
                           } 

можно заменить на

$img = $match[count($match) - 1][0];

Примерно так:

if (preg_match('#<img\s[^>]*>#i', $content, $match)) {
    $img = $match[0]; //first image in file only
    $stuff = simplexml_load_string($img);
    $stuff = $stuff[src];
    return $stuff;
} else {
    return null; //no match found
}
0 голосов
/ 28 ноября 2008

Скорее всего, потому что "XML", выбираемый регулярным выражением, не является правильным XML по любой причине. Я бы, вероятно, пошел на более сложное регулярное выражение, которое вытянет атрибут src вместо использования SimpleXML для получения src. Этот REGEX может быть близок к тому, что вам нужно.

<img[^>]*src\s*=\s*['|"]?([^>]*?)['|"]?[^>]*>

Вы также можете использовать настоящую HTML-библиотеку, но я не уверен, какие опции существуют в PHP.

...