php preg_match_all html даты с ошибкой слэша - PullRequest
0 голосов
/ 03 декабря 2009

Я пытаюсь preg_match_all свидание с косой чертой между двумя тэгами HTML; однако его возвращаемое значение null.

вот HTML:

> <td width='40%' align='right'class='SmallDimmedText'>Last Login: 11/14/2009</td>

Вот мой код preg_match_all ()

preg_match_all('/<td width=\'40%\' align=\'right\' class=\'SmallDimmedText\'>Last([a-zA-Z0-9\s\.\-\',]*)<\/td>/', $h, $table_content, PREG_PATTERN_ORDER);

где $ h - HTML выше.

что я делаю не так?
заранее спасибо

Ответы [ 4 ]

3 голосов
/ 03 декабря 2009

Это (с первого взгляда) потому, что вы пытаетесь соответствовать:

Last Login: 11/14/2009

С этим регулярным выражением:

Last([a-zA-Z0-9\s\.\-\',]*)

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

Last([a-zA-Z0-9\s\.\-\',:/]*)

дает совпадение

Было бы лучше просто использовать DOM parser , а затем предварительно преобразовать регулярное выражение в результате поиска DOM? Это делает для более приятного регулярного выражения ...

EDIT

Другая проблема в том, что ваш HTML-код:

... 40% 'align =' right'class = 'SmallDimmedText'> ...

Там, где нет пробела между align = 'right' и class = 'SmallDimmedText'

Однако ваше регулярное выражение для этого раздела:

... 40% \ 'align = \' right \ 'class = \' SmallDimmedText \ '> ...

Там, где указано, есть пробел.

Использование DOM Parser Это избавит вас от головной боли, вызванной незначительными ошибками, чем вы можете сосчитать.

Просто чтобы дать вам представление о том, как просто анализировать с помощью Simple HTML DOM.

$html = str_get_html(...);
$elems = $html->find('.SmallDimmedText');
if ( count($elems->children()) != 1 ){
    throw new Exception('Too many/few elements found');
}
$text = $elems->children(0)->plaintext;

//parsing here is only an example, but you have removed all
//the html so that any regex used is really simple.
$date = substr($text, strlen('Last Login: '));
$unixTime = strtotime($date);
1 голос
/ 03 декабря 2009

Я согласен с Якоби.

Как минимум, удалите все ссылки на любые специфичные для HTML и просто сделайте регулярное выражение

preg_match_all('#Last Login: ([\d+/?]+)#', ...
1 голос
/ 03 декабря 2009

Моим первым предложением было бы минимизировать объем текста, который у вас есть в preg_match_all, почему бы просто не сделать между ">" и "<"? Во-вторых, я бы в конечном итоге написал это регулярное выражение, но не уверен, что это поможет: </p>

/>.*[0-9]{1,2}/[0-9]{1,2}/[0-9]{2,4}</

Это будет искать конец одного тега, затем любой символ, затем дату, а затем начало другого тега.

1 голос
/ 03 декабря 2009

вижу как минимум две проблемы:

  • в вашей строке HTML, между 'right' и class= нет пробела, и в вашем регулярном выражении есть один пробел
  • Вы должны добавить как минимум эти 3 символа в список совпавших символов, между []:
    • ':' (между "Авторизацией" и датой есть один) ,
    • '' (между «Last» и «Login» и между «:» и датой имеются пробелы) ,
    • и '/' (между частями даты)

С этим кодом, кажется, работает лучше:

$h = "<td width='40%' align='right'class='SmallDimmedText'>Last Login: 11/14/2009</td>";
if (preg_match_all("#<td width='40%' align='right'class='SmallDimmedText'>Last([a-zA-Z0-9\s\.\-',: /]*)<\/td>#", 
        $h, $table_content, PREG_PATTERN_ORDER)) {
    var_dump($table_content);
}

Я получаю этот вывод:

array
  0 => 
    array
      0 => string '<td width='40%' align='right'class='SmallDimmedText'>Last Login: 11/14/2009</td>' (length=80)
  1 => 
    array
      0 => string ' Login: 11/14/2009' (length=18)


Обратите внимание, я также использовал:

  • # как разделитель регулярных выражений, чтобы избежать экранирования
  • " как разделитель строк, чтобы избежать экранирования одинарных кавычек
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...