PHP: preg_replace () desen değiştirici e - evalution sonucunda garip davranışlar başvuruları geri görmezden görünüyor

2 Cevap php

Aşağıdaki durum düşünün: Ben özellikle bunun yanına bir "arama motoru" bağlantısını eklemek istediğiniz bir dize bağlantıları değiştirmek istiyor.

Düşünün: Bağlantı Başlık (S), burada S arama terimi olarak "Bağlantı Başlığı" ile Google'a bağlantı olacak gibi. PHP kodu bu 1:01 üretebileceği yüzden kodda bir gerçek hayat örneği dizesi ($ içerik) kopyalanan ettik.

// PCRE case-insensitive, all as a single string, ungreedy and evaluate PHP replace.
$content = '<h3 class="bgg2" style="padding: 4px 0px 4px 5px; font-size: 11px;">» <a href="/forum_detail.html?topic=3456&amp;start=20&amp;post=97145#p97145" class="nub" title="Xenoblade: Japanischer TV-Spot"><b>Xenoblade: Japanischer TV-Spot</b></a></h3>';

$replace = preg_replace('/(<a.*>)(.*)<\/a>/isUe', ('"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q=' . strip_tags(strtoupper('blah\2')) . '\">S</a>)"'), $content);

print($replace);

Output (incorrect): Xenoblade: Japanischer TV-Spot (S) -> when you look at the HTML it looks like this:

<a href="http://www.google.com/search?q=BLAH%3Cb%3EXenoblade:%20Japanischer%20TV-Spot%3C/b%3E">S</a>

The strtoupper() did get the literal string blah -> BLAH but not the \2 back reference from the regular expression?

Belki PHP fonksiyonlarının karşı değerlendirmenin zamanlaması çeşit - \ 2 geri başvurulan dize strtoupper() veya strip_tags() fonksiyonlar yürütülür ÖNCE kullanılır gibi görünüyor?

Herkes bu bevhaviour açıklamak nasıl biliyor mu?

-

Ben hala ben beklendiği gibi yukarıdaki kod çalışmıyor neden şaşkın değilim, preg_replace_callback kullanarak bir çözüm geliştirdik.

Referans Ben başarmak istediğinizi görmek için:

Solution

// I have to use PHP < 5.0 so create_function() will do the job.
$replace = preg_replace_callback('/(<a.*>)(.*)<\/a>/isU',
create_function('$matches', 'return $matches[1] . $matches[2] . \'</a>&nbsp;(<a href="http://www.google.com/search?q=\' . strip_tags(strtoupper($matches[2])) . \'">S</a>)\';'),
$content);

print($replace);

Output (correct): Xenoblade: Japanischer TV-Spot (S) -> when you look at the HTML it looks like this:

<a href="http://www.google.com/search?q=XENOBLADE:%20JAPANISCHER%20TV-SPOT">S</a>

2 Cevap

Değişim

'"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q=' . strip_tags(strkarşıupper('blah\2')) . '\">S</a>)"'

karşı

'"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q=" . strip_tags(strkarşıupper(\'blah\2\')) . "\">S</a>)"'

The strip_tags() function needs karşı be a part of the replacement string so it doesn't get evaluated before it gets passed karşı preg_replace().

Ben senin bir kaç şey karıştırma düşünüyorum. Geçti dize çalışır strtoupper() denilen sizi, denemek için ilk olarak. Bu dize almak 'blah\2' ve 'BLAH\2' haline dönecek. Bu sonuç üzerinde çalışan, ancak yedek desen değil. Yazdığın sanki ...

'"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q='  
 . strip_tags('BLAH\2') . '\">S</a>)"'

yerine desen olarak.