2009-12-02 3 views
0

Я пытаюсь preg_match_all дату со слэшами в ней, сидящей между 2 html тегами; однако его возвращающий нуль.php preg_match_all html даты с ошибкой слэша

вот 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); 

где $ ч является HTML-выше.

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

ответ

3

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

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 = 'правый' и класс = 'SmallDimmedText'

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

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

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

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

Просто, чтобы дать вам представление о том, насколько просто разбираться с использованием простой 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

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

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

с помощью этого кода, кажется, работает лучше:

$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) 


Примечание Я также использовал:

  • # как регулярное выражение разделителем, чтобы избежать того, чтобы избежать слэш
  • " как разделитель строки, в избегать выхода из одинарных котировок
1

My первое предположение заключалось бы в том, чтобы свести к минимуму количество текста, которое у вас есть в preg_match_all, почему бы просто не сделать между «>» и «<»? Во-вторых, я в конечном итоге писать регулярные выражения, как это, не уверен, если это поможет:

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

Это будет выглядеть в конце одного тега, то любой характер, то дата, то начало другого тега ,

1

Я согласен с Yacoby.

По крайней мере, удалить все ссылки на какой-либо из конкретных HTML и просто сделать регулярное выражение

preg_match_all('#Last Login: ([\d+/?]+)#', ... 
Смежные вопросы