PHP kapanış etiketini yoruma dönüştür


149

Komut dosyamdaki satırlardan biri, bir dizenin içinde bir PHP kapatma etiketi içeriyor. Normal çalışma altında bu bir soruna neden olmaz, ancak hattı yorum yapmam gerekiyor.

Ben bu satırı yorum çalıştık //, /* */ve #ancak bunları hiçbiri çalışmıyorsa, çözümleyici etiketi kapanış düşünüyor gerçek bir kapanış etiketi olması.

Söz konusu hat:

$string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i', '<br />', $string);
//                              ^^             ^^

Yukarıdaki satırı yorumlamak için ne yapabilirim?


18
Komik bir sorun, ama gerçek. Oy kullanıyorum.
Voitcus

17
AMAN TANRIM. İlk başta sorunun şüpheliydi, sorunun ne olduğunu sormaya hazır, ama sonra '?>' İçeren bir dize ile bir satır yorum yapmaya çalıştım ve anladım. Bu, phpsadness.com
lolesque

6
Böyle bir "özellik" in yararlılığı php.net/manual/en/language.basic-syntax.comments.php'de açıklanmıştır , tek astarlı olması durumunda faydalıdır <?php # echo 'simple';?>.
13'te lolesque

2
@lolesque Bu bağlantı için teşekkürler. İyiydi. Diğer dilleri de kapsayan bir dil: wiki.theory.org/YourLanguageSucks
Simon Forsberg

5
@ OndraŽižka tüm yaptığı tekrarlanan br etiketlerini kaldırmak. bir normal ifade bunun için iyi çalışır. Kötü olması bazen her zaman kötü olduğu anlamına gelmez.
Kip

Yanıtlar:


124

Bir hile kullanın: dizeyi iki parçadan birleştirin. Bu şekilde, kapanış etiketi ikiye kesilir ve artık geçerli bir kapanış etiketi değildir.'?>' --> '?'.'>'

Kodunuzda:

$string = preg_replace('#<br\s*/?'.'>(?:\s*<br\s*/?'.'>)+#i', '<br />', $string);

Bu //yorumların çalışmasını sağlayacaktır .

İçin /* */işe yorum, bölmek olurdu */çok diziyi:

$string = preg_replace('#<br\s*'.'/?'.'>(?:\s*<br\s*'.'/?'.'>)+#i', '<br />', $string);

Bütün olsa bile bazen Unutmayın daha iyi olur kalır zamanlar vardır, fakat açgözlü olmak kötüdür - parçalarının toplamından daha az . :)


@ppeterka Vay be, bunu düşünmedim bile. Teşekkür ederim.
v1n_vampire

1
Bu numarayı içeren bir dize için 2 gün önce C'de kullanmak zorunda kaldım??<
Ryan Amos

2
Muhteşem bir tane. Neden hiç böyle düşünmüyorum !?
San

73

En kolay yol

Normal ifadenizi tutmak için ayrı bir değişken oluşturun; bu şekilde preg_replace()ifadeyi yorumlayabilirsiniz :

$re = '#<br\s*/?>(?:\s*<br\s*/?>)+#i';
// $string = preg_replace($re, '<br />', $string);

Karakter sınıflarını kullanarak düzeltme

Satır yorumlarını düzeltmek için aşağıdaki gibi bir karakter sınıfının içine ?>girerek ayrılabilirsiniz >:

$string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i', '<br />', $string);
                                 ^ ^              ^ ^

Blok yorumları düzeltmek için aşağıdakilere uygulayabilirsiniz /:

$string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i', '<br />', $string);
                               ^ ^              ^ ^

Her iki yorum stilini de düzeltmek için / ve > kendi karakter sınıflarına koyabilirsiniz .

/xDeğiştiriciyi kullanarak düzeltme

x Modifiye - aka PCRE_EXTENDED- (bir karakter sınıfı içinde meydana dışında) normal bir ifadede zaman göz ardı edilen boşluklar ve yeni satır; bu sorunlu karakterleri ayırmak için boşluk eklemeyi mümkün kılar. Her iki yorum stilini de düzeltmek için:

$string = preg_replace('#<br\s* /? >(?:\s*<br\s* /? >)+#ix', '<br />', $string);
                               ^  ^             ^  ^

@Cthulhu +1 (ve elbette cevap için). Ayrıca (en azından benim için) bu normal ifadeyi anlamak biraz daha zor. Pek değil, ama bu normal ifadeyi görürsem şunu söyleyebilirim: Hmmm, neler oluyor? Ama bu düpedüz ve tamamen öznel.
ppeterka

1
@ppeterka Biraz katılıyorum, bu yüzden xdeğiştiriciyi kullanarak başka bir yol buldum :)
Ja͢ck

@Jack Nice, bunun için başka bir +1 verirdim, yeni bir şey öğrendim ... Regex değiştiricileri unutmaya devam ediyorum (nadiren onlardan ayrı kullanıyorum g) ...
ppeterka

@Jack Teşekkürler, çözümden normal ifade hakkında yeni şeyler öğreniyorum.
v1n_vampire

1
Normal ifadeyi önceki bir satıra ayırmak için +1. Normal ifadeyi aynı tutar, ancak yine de mantığın yorumlanmasına izin verir.

38

Girişimleriniz neden işe yaramadı:

// $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',...
                                   ^ doesn't work due to ?> ending php

/* $string = preg_replace('#<br\s*/?>(?:\s*<br\s*/?>)+#i',... */
                                 ^ doesn't work due to */ closing comment

Ne çalışıyor:

/* $string = preg_replace('#<br\s*[/]?>(?:\s*<br\s*[/]?>)+#i',... */
                                  ^ ^              ^ ^
// $string = preg_replace('#<br\s*/?[>](?:\s*<br\s*/?[>])+#i',...
                                    ^ ^              ^ ^

Daha ileri...

Yukarıdakilerden sonra, /*satırı yorumlamak için kullanabilmeniz gerekir . ?>Bozulmadan ayrılırsanız, //tüm satırı yorumlayamazsınız. Aşağıdaki metin , PHP yorumlayıcısının kontrolü dışında?> olan html olabilir , bu yüzden işe yaramaz.

Gönderen belgeler:

"Tek satırlı" yorum stilleri, hangisinin önce gerçekleştiğine bağlı olarak yalnızca satırın sonuna veya PHP kodunun geçerli bloğuna yorum yapar. Bu, // ...?> Veya # ...?> İşaretinden sonraki HTML kodunun yazdırılacağı anlamına gelir:?> PHP modundan çıkar ve HTML moduna döner ve // ​​veya # bunu etkileyemez.


Teşekkürler, hala bilmediğim pek çok şey ... Yardımcı oldu.
13'te v1n_vampire

4
Bu yazı çok daha fazlasını + 1'leri hak edecekti ... Sadece ayrıntılı bir açıklama için.
ppeterka

15

Başka bir fikir: Escape >(ve /bir /*...*/yorum kullanmak istiyorsanız ):

$string = preg_replace('#<br\s*\/?\>(?:\s*<br\s*\/?\>)+#i', '<br />', $string);

Normal olmayan bir motor tarafından "gereksiz" bir kaçış göz ardı edilir, ancak bu durumda yararlıdır (diğer cevaplarda belirtilen nedenlerden dolayı).


@ppeterka: Karakter sınıfı yerine ters eğik çizgi kullandım (ama evet, bir olayı kaçırdım. Teşekkürler!)
Tim Pietzcker

Üzgünüm, yorgun görünüyorum ... İkincisini fark ettim, orada kalan [] ...
ppeterka

10

Sorunu çözmek için neden karmaşık, okunması zor "püf noktaları" kullanıyorsunuz?

? kolaylık sağlamak için sadece bir nicelik kısayolu.

Sadece nicelleştiricinin uzun versiyonunu kullanın,{0,1} "minimum 0 maksimum 1 tekrar" anlamına gelir:

$string = preg_replace('#<br\s*/{0,1}>(?:\s*<br\s*/{0,1}>)+#i', '<br />', $string);

1
+1 Bu sayfa aklımızın gerisinde kalmak için normal ifadeler toplamak için çok iyi bir yer olmaya başlıyor.
ppeterka

1
@ppeterka, aslında diğer tüm cevapları "hileler" olarak adlandırırdım, ama cevabım kısayolun değil sadece nicelleştiricinin uzun sürümünü kullanıyor.
stema

3
Hiçbir suç, sadece benim sözlükte, daha kısa, daha uygun sözdizimsel şeker yerine bir ifadenin uzun sürümünü kullanarak bir numara da sayılır ...
ppeterka

8

RegEx hile kitabına eklemeye değer diğer birkaç yol :

Öncelikle RegEx için kompakt olabilir: /(<br\s*/?>)+/ive ile değiştirin<br /> önce RegEx'inizi (RegExP'i yönlendirme ile yüklemeye gerek yoktur) ve her zaman seçtiğiniz XHMTL satır sonu ile sonuçlanırsınız.

RegEx'inizi */son yorumu veya ?>bitiş komut dosyasını açmayacak şekilde değiştirmenin diğer yolları :

  • İyileştirici nicelik belirticiler kullanın : #(<br\s*+/?+>)+#i- temelde \s*+beyaz boşluk eşleştiği kadar bulduysanız ve tutarsanız ve/?+ eğer bir eğik çizgi bulursanız saklayın!
  • Kapsama \s*ve /*yakalama gruplarında =>#(<br(\s*)(/?)>)+#i

Canlı demolar: http://codepad.viper-7.com/YjqUbi

Biz iyelik davranışı da yorum yapma sorunu olduğunu atlar olduğunu en hızlı RegEx eğilip beri: demo açıkladı#(<br\s*+/?+>)++#i


Zor durumlarda yorum yapmaya gelince

Kodu değiştiremediğinizde veya zaten çok satırlı bir yorum kullandığınızda ve:

1. nowdoc kullanın :

    $string='Hello<br>World<br><br />World<br><br><br>Word!';
    <<<'comment'
    $string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
comment;

Canlı kod: http://codepad.viper-7.com/22uOtV

Not: Bir Yorumlu metin bir benzer bir yorumlu metin ancak içeriğe ayrıştırmak yok ve var olması gerekiyor yolvermeye ayırıcı içine 'tek tırnak '( not olduğunu biten sınırlayıcı idented edilemez , takip etmelidir ;ve yeni hat ! )

2. Bir goto ile kodun üzerinden atlayın :

$string='Hello<br>World<br><br />World<br><br><br>Word!';
goto landing;
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
landing:

Canlı örnek: http://codepad.viper-7.com/UfqrIQ

3. if(false)veya ile kodun üzerinden atlayın if(0):

$string='Hello<br>World<br><br />World<br><br><br>Word!';
if(0){
$string = preg_replace('#(<br\s*/?>)+#i', '<br />', $string);
}

Test: http://codepad.viper-7.com/wDg5H5

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.