bölü hata ile php preg_match_all html tarihleri

4 Cevap

Ben 2 html etiketleri arasına oturan slashesle bir tarih preg_match_all çalışıyor ettik; Ancak onun boş dönen.

Burada html:

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

İşte benim preg_match_all () kodudur

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

$ h Yukarıdaki html nerede.

what am i doing wrong?
thanks in advance

4 Cevap

Eğer maç için çalışıyoruz çünkü (hızlı bir bakışta) olduğunu:

Last Login: 11/14/2009

Bu regex ile:

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

Regex : gerekli karakterleri içeren ve / hangi metin dizesindeki dahil değildir. : Regex ilgili kısmını değiştirerek

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

Gives a match

Sadece bir DOM parser kullanın ve sonra DOM arama sonucu regex preform için daha iyi olurdu? Bu güzel regex için yapar ...

EDIT

Diğer konu HTML olmasıdır:

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

Align = 'sağ' ve sınıf arasındaki boşluk yoktur nerede = 'SmallDimmedText'

Ancak bu bölüm için regex olduğunu:

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

Bu gösterilir Nerede bir boşluk var.

Use a DOM Parser Bu size güvenebilirsiniz daha ince hataların neden daha fazla baş ağrısı kurtaracak.

Sadece sana Basit HTML DOM kullanarak ayrıştırmak için ne kadar basit bir fikir vermek için.

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

Ben en az iki sorun bakın:

  • HTML dizesinde, 'right' ve class= arasında boşluk yoktur, ve bir boşluk senin regex orada olduğunu
  • you must add at least these 3 characters to the list of matched characters, between the [] :
    • ':' (there is one between "Login" and the date),
    • ' ' (there are spaces between "Last" and "Login", and between ":" and the date),
    • ve '/' (between the date parts)

Bu kod ile, daha iyi iş gibi görünüyor:

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

Ben bu çıktıyı alıyorum:

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)


Note I have also used :

  • # bir regex ayırıcı olarak, eğik kaçmak zorunda kalmamak için
  • " bir dize sınırlayıcı olarak, tek tırnak kaçmak zorunda kalmamak için

Benim ilk önerim preg_match_all sahip metnin miktarını en aza indirmek olacaktır, neden sadece ">" ve "<" arasındaki yapmak değil mi? İkincisi, ben yardımcı emin, böyle regex değil yazma bitirmek istiyorum:

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

O zaman bir etiketi, daha sonra herhangi bir karakteri, sonra bir tarih, başka bir etiketin başında ve sonunda arayacaktır.

Ben Yacoby katılıyorum.

En azından, belirli bir HTML ve sadece düzenli ifade yapmak herhangi tüm referans kaldırmak

preg_match_all('#Last Login: ([\d+/?]+)#', ...