Preg_match_all regex değişkenlerini kullanma

3 Cevap php

Ben manzaralı temiz ve basit bir sözdizimi izin PHP bir sözde değişkeni ayrıştırıcı inşa ediyorum ve bir motor hayata varsa-tablolar. Şimdi iç içe kullanmak mümkün olmasını istiyorsanız-tablolar ve ben düşündüm basit, en zarif çözüm bir blok için işaretleyici olarak girinti yapan yüzlek kullanımı idi.

Yani bu temelde ben görünümünde arıyorum düzeni:

{if x is empty}
    {if y is array}
        Hello World
    {endif}
{endif}

Komut ilk if ifadesi bulmak ve aynı derinlikte endif ile eşleşir. True değerlendirir eğer iç blok de işlenecek.

Şimdi, sorun aşağıdaki kodda derinliği kullanmak için normal ifadeyi kurma yaşıyorum:

preg_match_all('|([\t ]?){if (.+?) is (.+?)}(.+?){endif}|s', $template, $match);

Temelde ([\t ]?) {endif} değişkeni çeşit kullanarak, ve hiçbir eşleşen {[(varsa deyimi tam olmayacak emin olun önce yerleştirilmesi için ilk maçı istiyorum 1)]} {if ...} ile aynı derinliğe.

Bana bunu tamamlamak yardımcı olabilir misiniz?

3 Cevap

\ 1 İlk maç içerecektir, bu nedenle bunu yapabilirsiniz:

preg_match_all('|([\t ]?){if (.+?) is (.+?)}(.+?)\1{endif}|s', $template, $match);

Ancak, bu mutlaka sekmelerin doğru sayısına göre öncesinde {endif}, yalnızca sonraki oluşum doğru geçtiği maç olmayacak.

(O {if} ve {endif} sayma tekrarlarını gerektirir beri) tanımladığınız dili düzenli değil çünkü, bu sorun için genel kullanım düzenli ifadeler olamaz.

Ne var klasik eşleşen parantez sorunun bir çeşididir.

Sen {if} ve {endif} oluşunda izlemek için Finite-state machine çeşit kullanarak daha iyi olurdu.

Eğer açık "endif" deyimini kullanarak yapıyorsanız, sizin blokları zaten kapatılmış, ve herhangi bir özel girinti yapmak için gerek yok edilir, sadece. {['{endif} / / {if. +?} (. +?)' maç (0)]}, diğer tarafta, ne python-hem girinti bloklar, sen {endif} (parantez) kurtulmak ve sadece girinti düzeyleri eşleşen alabilirsiniz, Eğer

  if condition
      this line is in the if block
      this one too
  this one not

Lütfen ifadesi böyle olacak

 /([\t]+)if(.+)\n((\1[\t]+.+\n)+)/

"Durum" maç 2 ve deyim vücut maç 3 olacak

1 aslında bu doğru ise /{if}((.(?!{if))+?){endif}/s iç içe işlemek gibi bir şey olmalıdır.