HTML Blok Etiketler İçeren değil Hatları Extract için Düzenli İfade

3 Cevap php

Ben HTML block tags içeren tüm bitişik satırları ayıklamak için bir düzenli ifade için arıyorum, ancak HTML içerebilir inline tags.

Örneğin, ben aşağıdaki metni varsa ...

bla bla bla bla
bla <code>bla bla</code> bla
bla bla bla bla
<img src="" alt="" />
bla bla bla bla
<div> bla bla bla
bla bla bla

... Ben aşağıdaki satırları tek ayıklamak istiyorum ...

bla bla bla bla
bla <code>bla bla</code> bla
bla bla bla bla
<img src="" alt="" />
bla bla bla bla

Bu normal bir ifade ile yapmak mümkün mü?

Update: PHP ile çalışıyorum ve ben de bu blok etiketlerin isimlerini içeren bir değişken var. It doesn´t matter if the block tag is an open tag or a close tag.

$blockTags = "h1|h2|h3|h4|h5|h6|hr|ol|ul|li|pre|blockquote|p|table|tr|td|div";

3 Cevap

Bakmayı kes. Senin görevin HTML etiketleri açık ve yakın zaman anlayabileceği bir ayrıştırıcı gerektirir ve bu klasik düzenli ifadeler yapamayacağı bir şeydir.

Modern regexes böyle bir hüner koparmak mümkün olabilir, ama (iyi, tam olarak değil, ama yakın) ve hiç davranışını değiştirmek gerekiyorsa, muhtemelen olacak dünyanın gördüğü en iğrenç undreadable regex inşa edecek Her şeyi yeniden sonuna kadar. Yani sizin için bunu yapmak için nispeten basit bir ayrıştırıcı yazmak, ve bir başkası daha sonra anlamaya çalışırken saat geçireceksiniz bazı regex uydurmak çalışırken saat harcamak yok.

Eğer bir regex soru sorarsanız arada, kullandığınız hangi dili belirtin. Farklı dillerde biraz farklı çalışır.

Peki, ne yapabilirdi, ilk gibi bir şey ile herhangi bir html etiketlerini içermeyen satırları filtre olabilir edilir

[^<>]*

çizgi herhangi bir html satır etiketleri varsa ve daha sonra kontrol edin:

<(/?)(code|img|...)(/?)>

And the rest would be supposed to contain block-tags.
Don't know if this is accurate enough for you though.

Bu "tek bir düzenli ifade" değil, ancak sizin giriş dizesi olduğunu düşünüyor, işi yapmalıyım $str:

$lines = explode(PHP_EOL, $str);
$linesToKeep = array();

foreach ($lines as $line) {
    if (!preg_match('#</?(' . $blockTags . ')>#', $line)) {
        $linesToKeep[] = $line;
    }
}

// Et voila ;-)
$strOK = implode(PHP_EOL, $linesToKeep);
var_dump($strOK);

Birkaç kelime:

  • (Eğer satır satır tutmak veya reddetmek istediğiniz gibi) hattında çalışmaya dize patlar.
  • o satır satır döngüler
  • hat <TAG> ya da </TAG> içermiyorsa, bu $linesToKeep dizi konur
  • sonunda, çıktıya dize o diziye ne inşa edilmiştir

Belki de olsa, yapmak için daha kısa bir yolu vardır ... Ama bu bir anlamak için yeterince kolaydır, ben (bazı tür "regex cehennem" ya da ne olursa olsun hiç kimse ^ ^ korumak mümkün olacağını değil) tahmin

Düzenleme: Ben OP yeniden okurken, ben son satırı bir açılış etiketi ile bir çizgi dışlamak istiyorsanız o ... benim koduyla değil iken, dışlanmış, ve fark ettim bunu, burada başka bir önerme hemen sonra bir :

$lines = explode(PHP_EOL, $str);
$linesToKeep = array();
$i = 0;
$numLines = count($lines);

for ($i=0 ; $i<$numLines ; $i++) {
    $line = $lines[$i];
    if (!preg_match('#</?(' . $blockTags . ')>#', $line)) {
        $linesToKeep[] = $line;
    } else {
        if (preg_match('#<(' . $blockTags . ')>#', $line)) {
            // Opening tag, skip next line too ?
            $i++;
        }
    }
}

$strOK = implode(PHP_EOL, $linesToKeep);
var_dump($strOK);

Eğer kapanış etiketi kadar satırları atlamak istiyorsanız, bunu yapabilirsiniz nerede $i++ koymak - ama ^ ^ (And "parsing" HTML by-hand might not be such a good idea, if you want to get to something complicated ^^ ) / anlamak okumak için zorlaştırmaya oluyor