Regex ile html etiketleri içinde yakalama içerik

3 Cevap php

Öncelikle, ben bu kötü bir uygulamadır farkındayım ve ben bile bu kadar diyerek birçok soru cevap var, ama netleştirmek için I am forced to use regex because this application stores regexes in a database and only functions this way. I absolutely cannot change the functionality

Şimdi ben her zaman normal ifadeler ile bu alışık değilim DOM yöntemlerini kullanın çünkü biz yol .. dışarı var ki o.

Ben first bitiş div etiketine kadar, intro içerik bölümü içinde her şey yakalamak istiyorum. Regex iç içe divlere başarısız eğer umurumda değil. Ben de alan (satır) karakterleri yakalamak gerekir.

<div class="intro-content">
<p>blah</p>
<br/>
<strong>test</strong>
</div>

Şimdiye kadar regex:

<div\s*class="intro-content">(.*)</div>

. karakter boşluk karakterleri maç olmayacak, çünkü bu tabii ki çalışmaz.

Ben sorulan soru yüzlerce olmuştur fark yok, ama ben sadece ziyaret soruları nerede o satırsonlarının için hesap değil çünkü (.*), yeterli olmaz ve (DOM öneri cevapları hariç) nispeten basit cevapları vardı Bazı regexes çok açgözlü.

Ben (bu bile mümkün gibi) her olasılığı için hesap verecek mükemmel, temiz bir çözüm aramıyorum - Ben sadece ben hareket ve 'aren daha modern uygulamaları üzerinde çalışabilirsiniz bu çözüm için çalışacak hızlı bir çözüm istiyor öyle korkunç kodlu.

3 Cevap

Eğer "tüm nokta" (ler) bayrağı etkinleştirmeniz gerekir gibi geliyor. Bu yapacaktır. satır sonları da dahil olmak üzere tüm karakterleri maç. Örneğin:

preg_match('/<div\s*class="intro-content">(.*)<\/div>/s', $html);

Sen not Böyle html ayrıştırmak için sıradanifade en kullanmalısınız. div etiketleri iç içe olabilir, ve regexp herhangi bir içerik yok çünkü, o ayrıştırmak için hiçbir yolu yoktur. Yerine HTML ayrıştırıcı kullanın. Örneğin:

$doc = new DomDocument();
$doc->loadHtml($html);
foreach ($doc->getElementsByClassName("div") as $div) {
  var_dump($div);
}

Bkz: DomDocument

Edit:

Ve sonra ben senin notunu gördüm:

Ben bu uygulama mağazaları bir veritabanı ve tek fonksiyonları bu şekilde Regexes çünkü regex kullanmak zorunda duyuyorum. Ben kesinlikle işlevselliğini değiştiremezsiniz

Peki. En azından maç emin olun non-greedy. Sürece hiçbir iç içe etiketleri var gibi doğru maç olacak Bu şekilde:

preg_match('/<div\s*class="intro-content">(.*?)<\/div>/s', $html);

. karakter boşluk karakterleri maç olmayacak, çünkü bu tabii ki çalışmaz.

Yapmak gerekir, ama öyle değil, biz sadece onları ekleyebilirsiniz:

<div\s*class="intro-content">([ \t\r\n.]*)</div>

Eğer o zaman tembel yapmak gerekir, bu yüzden first </div> ve son değil, kadar her şeyi yakalar. Biz bir soru işareti ekleyerek bunu:

<div\s*class="intro-content">([ \t\r\n.]*?)</div>

Orada. Bir atış ver. Tek bir \s çok ile ( \t\r\n) [ ve ] arasındaki boşluk karakterleri değiştirmek mümkün olabilir.