Belirli etiketleri içinde içerik sayarak, HTML bloğunu Süreci

4 Cevap php

Bir blogda ben güzel tipografik karakterlerin içine tırnak ve diğer bazı öğeleri işlemek için bir PHP komut dosyası aracılığıyla bir blog girişi için metnin tüm geçmek istiyoruz.

Söz konusu blog metni HTML içeren ve özellikle <pre><code> ... </code></pre> blokları içinde bulunan kod parçacıkları vurgular. code blokları (çok yığın taşması gibi!) Rastgele ve metin içinde birden fazla yerde görünebilir

I do not want those code blocks processed by the typographic scripts I will be using. The processing itself is not the point, being able to selectively apply it is.

O blokları bulmak için bir regex yazmak mümkün olmuştur:

preg_match_all('/(<pre><code>(.*?)<\/code><\/pre>)/s', $text, $matches);

Ama en iyi yolu metnin kalanını işlemek ve sonra geri onların doğru yerlere bu blokları yarmak ne olduğundan emin değilim.

Yardımlarınız için teşekkürler!

4 Cevap

Aklıma gelen ilk çözüm bu gibi görünüyor:

  • tüm kodları çıkarmak
  • Dizenizin manipülasyonlar etkilenmez olmayacak özel bir işaretleyici ile bunların yerine, kodları kaldırmak - ki işaretleyici gerçekten özel olmak zorundadır (ve bunu btw, giriş dizesi mevcut değil doğrulamak olabilir)
  • dize üzerinde manipülasyonlar yapmak
  • belirteçleri artık var kodları, geri koymak

In code, it could be something like this : (sorry, it's quite long -- and I didn't include any check ; it's up to you to add those)

$str = <<<A
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec sodales lacus et erat accumsan consectetur. Sed lacinia enim vitae erat suscipit fermentum. Quisque lobortis nisi et lacus imperdiet ac malesuada dui imperdiet. <pre><code>ThIs Is 
CoDe 1</code></pre>Donec vestibulum commodo quam rhoncus luctus. Nam vitae ipsum sed nibh dignissim condimentum. Sed ultrices fermentum dapibus. Vivamus mattis nisi nec enim convallis quis aliquet arcu accumsan. Suspendisse potenti. Nullam eget fringilla nunc. Nulla porta justo justo. Nunc consectetur egestas malesuada. Mauris ac nisi ipsum, et accumsan lorem. Quisque interdum accumsan pellentesque. Sed at felis metus. Nulla gravida tincidunt tortor, <pre><code>AnD cOdE 2</code></pre>nec aliquam tortor ultricies vel. Integer semper libero eu magna congue eget lacinia purus auctor. Nunc volutpat ultricies feugiat. Nullam id mauris eget ipsum ultricies ullamcorper non vel risus. Proin volutpat volutpat interdum. Nulla orci odio, ornare sit amet ullamcorper non, condimentum sagittis libero. <pre><code>aNd
CoDe
NuMbEr 3
</code></pre>Ut non justo at neque convallis luctus ultricies amet. 
A;
var_dump($str);

// Extract the codes
$matches = array();
preg_match_all('#<pre><code>(.*?)</code></pre>#s', $str, $matches);
var_dump($matches);

// Remove the codes
$str_nocode = preg_replace('#<pre><code>.*?</code></pre>#s', 'THIS_IS_A_NOCODE_MARKER', $str);
var_dump($str_nocode);

// Do whaterver you want with $str_nocode
$str_nocode = strtoupper($str_nocode);
var_dump($str_nocode);

// And put back the codes :
$str_codes = $str_nocode;
foreach ($matches[0] as $code) {
    $str_codes = preg_replace('#THIS_IS_A_NOCODE_MARKER#', $code, $str_codes, 1);
}
var_dump($str_codes);

Ben denedim:

  • bir satırda kod,
  • 2 satır kodu,
  • ve birden fazla satır kodu

Not: Eğer gerçekten daha yaptım daha test etmelisiniz - ama bu size bir ilk fikir verebilir ...

Bu :-) yardımcı olur umarım

Bir yan not olarak: genellikle regexes ile HTML ayrıştırma kötü uygulama olarak kabul edilir ve genellikle Belki DOMDocument::loadHTML bir göz değer olan bir fikir olabilir gibi bir şey kullanarak ... sıkıntılara yol açar?

: Eğer geri preg_match_all() o preg_split() şöyle kaldıraç gereken her şeyi alıyorsanız

$pattern = '/(<pre><code>(.*?)<\/code><\/pre>)/s';

// get the code blocks
preg_match_all($pattern, $text, $matches);
$code_blocks = $matches[0];

// split up the text around the code blocks into an array
$unprocessed = preg_split($pattern, $text);
$processed_text = '';
foreach($unprocessed as $block) {

    // process the text here
    $processed_text .= process($block); 

    // add the next code block
    if(!empty($code_blocks)) $processed_text .= array_shift($code_blocks);
}

// any remaining
$processed_text .= implode('', $code_blocks);

Bu yapmak zorunda talihsiz dezavantajı var birden fazla process(), böylece ne kadar yoğun ve ne sıklıkta bunu bağlı olarak bu en iyi çözüm olmayabilir çağırır. Bu rağmen oldukça açık ve güvenli olduğunu ve daha sonra değiştirilmesi için herhangi bir özel işaretinin eklenmesi gerekmez.

Lütfen işleme beyaz listeleme ve güvenlik türü şeyler yapıyor o zaman bu tür şeyler önlemek izin verebilir HTML bazı gelişmiş filtreleme yapabilirsiniz HTMLPurifier bakabilirsiniz tamamen (o düşünceden bana teklif etmeyin .)

Ben markdown gibi metin biçimlendirme ve HTML sağlar Textile hangi kullanmanızı öneririz. Bu süper kullanımı kolay ve ben doğru anlamak eğer sorunu çözmek gerektiğini düşünüyorum.

Sadece tırnak, veya öğelerin küçük bir listesini dönüştürmek için arıyorsanız, ben sadece string_replace kullanabilirsiniz.

$text = <<

Some code here

Yorumlu metinler;

$search_and_replace = array('"', '"', "'", '''); $newtest = str_replace( array_keys( $search_and_replace ), $search_and_replace, $text);

Eğer saklamak istediğiniz HTML etiketleri belirlemenizi sağlar strip_tags gibi bir şey arıyoruz sürece.