簡體   English   中英

PHP regex,preg_replace_callback,在1個字符串中失敗,有2個可能的匹配

[英]PHP regex, preg_replace_callback, failing with 2 possible matches in 1 string

我正在玩這個非常基礎的課程,以了解有關正則表達式的更多信息。 我想要實現的是從testview文件中獲取內容,在{{EACH slides}}和{{#EACH}}之間准確抓取字符串。 現在在類中出現的正則表達式就是這樣,加上開始標記中的變量名。 然后我想使用該字符串用正確的變量循環它並將其放回原位。

但是當我在視圖中使用2個EACH循環而不是1時,它會嚴重失敗。 preg_replace_callback()將匹配第一個開始標記和第二個循環的最后一個結束標記,並給出如下字符串:

"htmlbalalbal {{#EACH}} more htmlblabla {{EACH newsitems}} htmlblalblabla"

從:

<div class="rows-container">
{{each slides}}
    <div class="row flex-wrap" data-id="{{id}}">
    </div>
{{#each}}
</div>
<div class="rows-container">
{{each blogposts}}
    <div class="row flex-wrap" data-id="{{id}}">
    </div>
{{#each}}

我一直在嘗試改變正則表達式一段時間了,我開始看到越來越多的邏輯......但我還沒有解決我的問題。 是否有可能走這條路? 或者我是否需要另一種解決方案來掃描我的測試文件中的多個EACH循環? 我可能很快會使用一些框架,但是當我在周末感到無聊的時候,我喜歡這樣做...

class Aclass{

    private $each = '~\{\{each ([^{]*)\}\}([^*]*)\{\{\#each\}\}~i';

    private $current_file_content = "";
    private $testviews = ['/testview.php'];

    private $views;

    function __construct($views){
        $this->views = $views; //not in use
        $this->start();
   }

   private function start(){
        foreach($this->testviews as $file){
            $this->current_file_content = file_get_contents(ROOT.$file);
            $this->scan_each();
        }
   }

   private function scan_each(){
       $result = preg_replace_callback($this->each, [$this, '_each'], $this->current_file_content);
   }


    private function _each($matches){
        foreach($matches as $match){
            var_dump(htmlspecialchars($match));
            echo '<br><br>';
        }
    }

編輯:16-5所以,我一直在進一步..它的工作很好,但它並沒有覆蓋每個內部的每一個。 這是一種類似的情況,我認為將來可能會有用:

{{each attributes}}
<label>{title}</label>
<select name="{key}" id="{key}" class="select">
    <option value="0" selected>choose an option</option>
    {{each values}}
        <option value="{id}" {selected}>{title}</option>
    {{#each}}
</select>
{{#each}}

我一直在想是否有辦法在1個正則表達式中覆蓋它,然后如果處理外部每個循環的函數看到每個內部的另一個,它將首先完成該1。 我完全願意自己構建這些功能,但獲得一些技巧會很棒。 你會建議分離正則表達式嗎? 找到{{each X}}和{{#each}}並在php中以另一種方式修復它,或修復已回答的Regex以便能夠處理這個問題?

您的正則表達式可以修復為

'~{{each\s+([^{}]*)}}(.*?){{#each}}~is'

請參閱正則表達式演示

這里的要點是你在模式中使用的[^*]匹配任何字符但*需要匹配一個字符串和另一個字符串之間的任何0+字符。 它可以用.*?來實現.*? s修飾符。

細節

  • {{each - 一個文字子串
  • \\s+ - 1+個空格
  • ([^{}]*) - 第1組:除{}以外的零個或多個字符
  • }} - 一個文字}}子字符串
  • (.*?) - 第2組:任何0+字符,盡可能少(由於懶惰的*?量詞)
  • {{#each}} - 文字{{#each}}子字符串。

用以下代碼替換您的代碼:

private $each = '~{{each\\s+(.+?)}}(.+?){{#each}}~is';

RegEx101演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM