2013-12-11 2 views
0

Я полный новичок с регулярными выражениями, и теперь я плохо себя чувствую, когда мне нужен серьезный совет о том, как извлечь имя ссылки из тега ahref, т.е.Имя тега href

<a href="article.html?id=1999874">This article is cool</a> 

и мне нужно было бы извлечь «Эта статья крут», обращая внимания, что «article.html? ID =» не избежать. Я пробовал с

preg_match_all('/<a href="article.html?id=([0-9])">([^<]*)<\/a>/', $webpage, $match); 

и что я вернусь весь

Array ([0] => Array () [1] => Array () [2] => Array ()) 

Спасибо за любые ценные советы!

+0

Связанные: http://stackoverflow.com/a/1732454/1415038 – woz

+1

'[0-9] +', потому что идентификатор содержит многократный цифры, также escape '?' –

+0

** Не используйте регулярные выражения для синтаксического анализа HTML. Используйте подходящий модуль синтаксического анализа HTML. ** Вы не можете надежно проанализировать HTML с регулярными выражениями, и вы столкнетесь с печалью и разочарованием в будущем. Как только HTML изменится с ваших ожиданий, ваш код будет сломан. См. Http://htmlparsing.com/php или [этот поток SO] (http://stackoverflow.com/questions/3577641/how-do-you-parse-and-process-html-xml-in-php) для примеры правильного анализа HTML с PHP-модулями, которые уже были написаны, протестированы и отлажены. –

ответ

0

Onetrickpony попал в сердце, что не так с вашим регулярным выражением: ваш цифровой идентификатор имеет несколько цифр, но ваше регулярное выражение соответствует только одной цифре.

Есть еще кое-что, что я собираюсь выбросить там для вашего рассмотрения. Во-первых, если в вашем теге <a> есть другие атрибуты, ваше регулярное выражение не будет выполнено. Например, если есть атрибут target="_blank", это испортит ваше регулярное выражение. К счастью, есть простой способ обойти, что:

preg_match_all('/<a .*?href="article\.html\?id=([0-9]+)".*?>(.*?)<\/a>/', 
    $webpage, $match); 

По сути, я просто проложенный атрибут href.*? с. Вопросительный знак делает совпадения lazy (вместо значения по умолчанию жадный), что предотвратит его потребление больше, чем вы хотите. Я также заменил ваш [^<] ленивым матчем, потому что я обычно считаю его немного чище.

ОБНОВЛЕНИЕ: Как указано правильно, указатель периода и вопроса в article.html?id= должен быть экранирован. Период не имеет большого значения, за исключением того, что оставить его там будет article_html или что-нибудь еще, что, вероятно, не вызывает беспокойства. Однако не избежать вопросительного знака - проблема. Это делает l в html необязательным, но тогда нет ничего, на самом деле совпадающего с вопросительным знаком, и, вероятно, поэтому мое исправленное решение не срабатывало. Спасибо, демона!

+0

Чем вы отвечаете за свой ответ, но тем не менее, я получаю обратно с $ match: Array ([0] => Array() [1] => Array() [2] => Array()) – Sates

+0

Проблема здесь что вам нужно избегать? и. (точка), потому что это элементы регулярного выражения. – demonking

+0

О, вы правы в вопросе?. Выйти из этой точки не так важно, но вы технически верны. Хороший звонок, демонстрация. –

0

Ваше регулярное выражение должно выглядеть примерно так:

<a(.+)?href="article\.html\?id=([0-9]+?)">(.+)?<\/a> 

Проблема будет, если кто-то будет включать в себя некоторые классы или идентификаторы для вашего A HREF. Тогда регулярное выражение не будет работать должным образом.

Пример:

<?php 

$str = '<a href="article.html?id=1999874">This article is cool</a>'; 

$matches = array(); 

preg_match_all('/<a.?href="article\.html\?id=([0-9]+?)">(.+)?<\/a>/',$str,$matches); 

var_dump($matches); 


?> 

Выход:

array(3) { 
    [0]=> 
    array(1) { 
    [0]=> 
    string(58) "<a href="article.html?id=1999874">This article is cool</a>" 
    } 
    [1]=> 
    array(1) { 
    [0]=> 
    string(7) "1999874" 
    } 
    [2]=> 
    array(1) { 
    [0]=> 
    string(20) "This article is cool" 
    } 
} 
+0

nopes, не работает – Sates

+0

Я протестировал его, и он отлично работает, см. Мое редактирование – demonking

+0

Я лично не буду использовать '

Смежные вопросы