Regex HTML bir çizgi bulmak için doğru aracı mı?

7 Cevap php

Ben bir sunucunun kapalı bazı içerik çeker bir PHP komut dosyası var, ama sorun içeriği hangi çizgi her gün değişir, bu yüzden ben sadece belirli bir çizgi çekin olamaz. Ancak, içerik benzersiz bir kimliği vardır, bir div içinde bulunur. Bu mümkün mü (ve en iyi yoldur) regex bu benzersiz kimliği aramak ve daha sonra benim script sırtında bulunuyor hangi hattı geçmek için?

Örnek:

HTML dosyası:

<html><head><title>Example</title></head>
<body>
<div id="Alpha"> Blah blah blah </div>
<div id="Beta"> Blah Blah Blah </div>
</body>
</html>

Yani ben alpha bir kimliği ile bir açılış div etiketiyle hat arıyorum diyelim. Üçüncü satırda alpha kimliği ile div çünkü kod, 3 dönmelidir.

7 Cevap

Satır numarası burada değil div gerçek içeriği sizin için önemli olduğundan, ben hiç regex kullanmak için değil meyilli olurdu. Herhalde bu dizi boyunca bir dizi ve döngü içine explode() dizesi işaretleyici arıyor olurdu. Şöyle:

<?php
$myContent = "[your string of html here]";
$myArray = explode("\n", $myContent);
$arraylen = count($myArray); // So you don't waste time counting the array at every loop
$lineNo = 0;
for($i = 0; $i < $arraylen; $i++)
{
     $pos = strpos($myArray[$i], 'id="Alpha"');
     if($pos !== false)
     {
          $lineNo = $i+1;
          break;
     }
}
?>

Yasal Uyarı: Bu test etmek için hazır bir php kurulumu yüzden bazı hata ayıklama gerekebilir yok.

Bir kerelik özellikle eğer - Ben muhtemelen sadece sadece çok basit bir şey yapmak için bir ayrıştırma motoru uygulamak için zaman kaybı olacak düşünüyorum Umarım bu yardımcı olur.


Edit: içeriği bu aşamada size güçsüz ise çok daha sonra iş için yeterli bir regex sağlayan diğer yanıtlar ile birlikte kullanabilirsiniz.


Düzenleme # 2: Ah ne hey ... Burada benim iki sent:

"/<div.*?id=\"Alpha\".*?>.*?(<div.*//div>)*.*?//div>/m"

(<div.*//div>) bu iç içe div etiketleri bulabilirsiniz ve yerine sadece ilk </div> durdurma daha onları bulursa sadece Maçın onları birleştirmek için regex motoru söyler. Yuvalanma sadece bir seviye varsa Ancak bu sadece sorunu çözer. Daha fazla varsa, o regex özür için değil: (.

/m da [\S\s] ile her yerde kirli up ifadeler zorunda kalmamak regex motoru linebreaks görmezden yapar.

Yine, üzgünüm, ben hata ayıklama gerekebilir yüzden şu anda bu test için herhangi bir ortam var.

Cheers Iain

Zaten delilik dağları geçti Jeff için daha yukarı oy sağlama riski az ... see here

Argüman ileri geri öfkeleniyor, ama ... bu kadar basit bir-off ya da az kullanılan komut daha karmaşık ve verdiği küçük bir geleceği olan, güvenilir olması gerekir eğer, o zaman emin kullanımı regex yazıyorsunuz o zaman ben bir kullanmanızı öneririz HTML ayrıştırıcı. HTML ehlileştirmek için bir kötü genellikle non-düzenli bir canavar. Belki senin durumunda bu regex, ya da belki de onun tam gaz ayrıştırıcı ... iş için doğru aracını kullanın.

Genel olarak, NO. Eğer div her zaman bir satır veya there is not another div inside it olacağından eminiz Ama eğer sorun olmadan kullanabilirsiniz. /<div id=\"mydivid\">(.*?)</div>/ ya da benzer bir şey gibi bir şey.

Aksi takdirde, DOMDocument daha aklı başında bir yol olacaktır.

EDIT HTML Örneğin bakınız. Benim cevabım "YES" olacaktır. RegEx bunun için çok iyi bir araçtır.

Ben değil hatları (biraz farklı olacaktır) gibi sürekli bir metin olarak HTML olduğunu varsayalım. Ben de satır numarasını satır içeriği daha bunu istiyorum varsayalım.

İşte bunu ayıklamak için bir rought PHP kodu olduğunu. (Sadece bazı fikir vermek için)

$HTML =
"<html><head><title>Example</title></head>
<body>
<div id=\"Alpha\"> Blah blah blah </div>
<div id=\"Beta\"> Blah Blah Blah </div>
</body>
</html>";

$ID = "Alpha";

function GetLineOfDIV($HTML, $ID) {
    $RegEx_Alpha = '/\n(<div id="'.$ID.'">.*?<\/div>)\n/m';
    $Index       = preg_match($RegEx_Alpha, $HTML, $Match, PREG_OFFSET_CAPTURE);
    $Match       = $Match[1]; // Only the one in '(...)'
    if ($Match == "")
        return -1;

    //$MatchStr    = $Match[0]; Since you do not want it, so we comment it out.
    $MatchOffset = $Match[1];

    $StartLines = preg_split("/\n/", $HTML, -1, PREG_SPLIT_OFFSET_CAPTURE);
    foreach($StartLines as $I => $StartLine) {
        $LineOffset = $StartLine[1];
        if ($MatchOffset <= $LineOffset)
            return $I + 1;
    }
    return count($StartLines);
}

echo GetLineOfDIV($HTML, $ID);

Sana bir fikir vermek umuyoruz.

Benzersiz bir kimliği dahil olduğu gerçeği, umut verici sesler, ama bir DIV ve HTML ille tek bir satır olacak, çünkü bu normal bir ifade oluşturmak için zor olacak, ve regexes ile HTML ayrıştırma için olağan itirazlar uygulayın.

Tavsiye edilmez.

Bunun yerine RegEx'in, özellikle (dağınık) HTML işlemek için yapılmış bir ayrıştırıcı kullanın. Bu biraz HTML değişiklikleri durumda uygulama daha az kırılgan yapacak ve Regex'in veri yeni bir parça çekin istediğiniz her zaman özel-zanaat el gerekmez.

Bu yığın taşması sayfasına bakınız: Mature HTML Parsers for PHP

@ Gereksinimi beri OP kolay, sadece dize yöntemleri kullanabilirsiniz olmasıdır

$f = fopen("file","r");
if($f){
    $s="";
    while( !feof($f) ){
        $i+=1;
        $line = fgets($f,4096);        
        if (stripos($line,'<div id="Alpha">')!==FALSE){
            print "line number: $i\n";
        }
    }
    fclose($f);
}