正则表达式递归代码块内容

时间:2015-08-02 07:12:44

标签: php regex recursion blade

我要求使用RegEx获取2个指令(embedendembed)之间的内容。我当前的模式正确地执行了此操作/(?<!\w)(\s*)@embed(\s*\(.*\))([\w\W]*?)@endembed/g

但是,当指令嵌套时,它与正确的块不匹配。 https://regex101.com/r/nL8gV5/2

@extends('layouts/default')

@section('content')
    <div class="row">
        <div class="col-md-6">
            @embed('components/box')
                @section('title', 'Box title')
                @section('content')
                    <h4>Haai</h4>
                    Box content
                @stop
            @endembed
        </div>
        <div class="col-md-6">
            @embed('components/box')
                @section('title', 'Box2 title')
                @section('content')

                    @embed('components/timeline')
                        @section('items')
                        @stop
                    @endembed

                @stop
            @endembed
        </div>
    </div>
@stop

期望的输出:

1:    
@section('title', 'Box title')
@section('content')
    <h4>Haai</h4>
    Box content
@stop

2:
@section('title', 'Box2 title')
@section('content')
    @embed('components/timeline')
        @section('items')
        @stop
    @endembed
@stop

3:
@section('items')
@stop

我尝试了各种模式,但我似乎无法做到正确。根据我的理解,我应该使用(R?)递归令牌和反向引用?更像是https://regex101.com/r/nL8gV5/3的东西。花了几个小时摆弄,我仍然没有工作。

我做错了什么,正确的模式是什么?

2 个答案:

答案 0 :(得分:1)

我从一个例子中得到了这个递归正则表达式(来自这个stackoverflow answer):

if translate_this[0] =~ /^[aeiou]/

regex101

上试用

答案 1 :(得分:1)

要捕获外部@embed和嵌套的$pattern = '/@embed\s*\([^)]*\)((?>(?!@(?:end)?embed).|(?0))*)@endembed/s'; ,请使用recursive regex

(?0)

$1粘贴图案。见test at regex101。在匹配时替换为已捕获的$res = array(); while (preg_match_all($pattern, $str, $out)) { $str = preg_replace($pattern, "$1", $str); $res = array_merge($res, $out[1]); }

/@embed\b(?>(?!@(?:end)?embed\b).|(?0))*@endembed/s

这将为您提供直到最里面的外部和嵌套的。 Test at eval.in

没有任何捕获的基本递归模式就像as this

一样简单
@embed
  • 匹配文字\b后跟(?> word boundary
  • (?!@(?:end)?embed).使用非捕获atomic group进行更改:
  • 替代:@embed字符that starts not @endembed|(?0) )*或从开始粘贴模式。 @endembed整个事情都是无数次。
  • 匹配文字s (PCRE_DOTALL)

使用process = subprocess.Popen(["inotifywait", "-q", "-r", "-m", "--format", "%e:::::%w%f", srcroot], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) flag使dot也匹配换行符