[英]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.