簡體   English   中英

嵌套PCRE正則表達式問題

[英]Nested PCRE Regex Issue

我有一個自定義模板引擎。

它抓住了這個:

@function(argument1 argument2 ...)
@get(param:name)
@get(param:@get(sub:name))

和這個 :

@function(argument1 argument2 ...)

    Some stuff @with(nested:tag)

    @foreach(arguments as value)
        More stuff : @get(value)
    @/foreach

    @function(other:args)
        Same function name (nested)
    @/function

@/function

使用這種模式(PCRE / PHP):

#

@ ([\w]+) \(

( (?: [^@\)] | (?R) )+ )

\)

(?:
    ( (?> (?-2) ) )

    @/\\1
)?

#xms

這個正則表達式捕獲幾乎所有結果。 但是,當我有更多的嵌套(或沒有)標簽時,它什么也收不到。 例如 ,當我做2個嵌套的@foreach(var:name) ... @/foreach ,根據標簽內容spaces ,正則表達式將失敗。

使用命名子模式有時會更清晰。 我建議您使用此:

~
@(?<com>\w+)                 # command name
\s*                          # possible white characters before args
(?: \( (?<args>[^)]*) \) )?+ # eventual parameters
(?:
    (?<content>(?:[^@]+|(?R))*+) # content (maybe empty)
    @/\g{com}                    # close the command
)?+                          # optional
~

如果需要允許在參數內使用命令,則可以將(?<args>[^)]*)替換為(?<args>(?:[^@)]+|(?=@)(?R))*+)

但是,當您嘗試描述一種語言時,一種更好的方法是使用(?(DEFINE)...)語法首先在主要模式之前描述元素,例如:

$pattern = <<<'EOD'
~
(?(DEFINE)
    (?<command_name> \w+ )
    (?<inline_command> @ \g<command_name> \s* \g<params>? )
    (?<multil_command> @ (\g<command_name>) \s* \g<params>? \g<content> @/ \g{-1} )
    (?<command> \g<multil_command> | \g<inline_command> )

    (?<other> [^@()]+ ) 
    (?<param> \g<other> | \g<command> )
    (?<params> \( \s* \g<param> (?: \s+ \g<param> )* \s* \) )

    (?<content> (?: \g<other> | \g<command> )* )
)
# main pattern
\g<command>
~x
EOD;

使用這種語法,如果要在底層提取元素,則只需將主模式更改為: @(?<com> \\g<command_name> ) \\s* (?<args>\\g<params> )? (?: (?<con> \\g<content> ) @/ \\g{com} )? @(?<com> \\g<command_name> ) \\s* (?<args>\\g<params> )? (?: (?<con> \\g<content> ) @/ \\g{com} )? (注意:要獲得其他級別,請先行考慮)

暫無
暫無

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

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