Recursively eşleşen PHP regex

2 Cevap php

I'm trying to match a certain set of tags in a template file. I however want the tags to be able to be nested in itself.

Benim regex takip ediyor: (/ s)

<!-- START (.*?) -->(.*?)<!-- END \\1 -->

Örnek Etiketi:

<!-- START yList -->
  y:{yList:NUM} | 
  <!-- START xList -->
    x:{xList:NUM} 
  <!-- END xList -->
  <!-- CARET xList -->
  <br>
<!-- END yList -->
<!-- CARET yList -->

Şu anda maçlar neden olacaktır:

match 0:

grubu (0) (Tüm maç)

<!-- START yList --> 
 y 
 <!-- START xList --> 
   x 
 <!-- END xList --> 
 <!-- CARET xList --> 
 <br> 
<!-- END yList -->

Grup (1)

yList

Grup (2)

y 
<!-- START xList --> 
  x 
<!-- END xList --> 
<!-- CARET xList --> 
<br>

I want 2 matches instead of 1 obviously, the nested tag set isn't matched. Is this possible with regex, or should I just keep regexing Grup (2) results, untill i've found no new matches?

2 Cevap

Böyle bir şey yapabilirsiniz:

$parts = preg_split('/(<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$tokens = array();
$isTag = isset($tokens[0]) && preg_match('/^<!-- (?:START|END|CARET) [a-zA-Z][a-zA-Z0-9]* -->$/', $tokens[0]);
foreach ($parts as $part) {
    if ($isTag) {
        preg_match('/^<!-- (START|END|CARET) ([a-zA-Z][a-zA-Z0-9]*) -->$/', $token, $match);
        $tokens[] = array($match[1], $match[2]);
    } else {
        if ($token !== '') $tokens[] = $token;
    }
    $isTag = !$isTag;
}
var_dump($tokens);

Bu size kod yapısını verecektir.

Düzenli ifadeler keyfi-derinlik ağaç yapıları ayrıştırma için uygun değildir. Bu kullandığınız regex lezzet bağlı olarak, yapmak mümkün olabilir, ancak tavsiye değil - onlar da hata ayıklamak için okumak zor ve zordur.

Bunun yerine, basit bir ayrıştırıcı yazma öneririm. Yapmanız olası bir dizi halinde metin ayrıştırmak olduğunu tokens Her basit düzenli ifadeler ile tanımlanabilir ki, örneğin:

START_TOKEN = "<!-- START [A-Za-z] -->"
END_TOKEN = ...
HTML_TEXT = ...

Lütfen dize üzerinde yineleme ve sürece bu belirteçleri maç gibi, dize çekip çıkarın ve ayrı bir listede saklayabilirsiniz. Bunu yaptığınızda belirteci (varsa) içinde oldu metni kaydetmek için emin olun.

Sonra jeton listenizde üzerinde yineleme ve belirteç türlerine dayalı her içeren, düğüm iç içe geçmiş bir ağaç yapısı oluşturmak ya 1) orijinal belirteci metin, ve çocuk düğümler 2) bir liste.

Bu çok karmaşık görünüyor eğer bazı ayrıştırıcı öğreticiler bakmak isteyebilirsiniz.