编写表达式以在括号之间递归提取数据

时间:2015-05-25 19:48:39

标签: php regex recursion tokenize

我正在尝试编写一个正则表达式,将字符串拆分为匹配花括号内的单独元素。首先,它需要递归,其次,它必须返回偏移量(如PREG_OFFSET_CAPTURE)。

我实际上认为这可能是处理这些数据的一种效率较低的方法,但我不确定更简单,性能更强的技术。 (如果你有一个,我很乐意听到它!)

因此,输入可以采用以下格式:

Hello {#name}! I'm a {%string|sentence|bit of {#random} text}

如果数据采用格式,则处理数据非常简单:

Hello {#name}! I'm a {%string|sentence|bit of random text}

但它是另一组花括号中的递归花括号,这是处理时的问题。 我正在使用以下代码来拆分字符串:

preg_match_all("/(?<={)[^}]*(?=})/m", $string, $braces, PREG_OFFSET_CAPTURE);

如前所述,这对于简单的形式来说非常好。对于更复杂的形式,更不用说了。这个的意图(我让它以非递归形式运行)是用函数处理的内容替换每个带括号的区域,向上工作。

理想情况下,我希望能够编写Hello {#name}! I'm a {%string|sentence|bit of {?(random == "strange") ? {#random} : "strange"}} text}并使其易于管理。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

您可以利用PCRE正则表达式捕获前瞻和子例程中的组来获取嵌套的{...}子字符串。

A regex demo is available here

$re = "#(?=(\{(?>[^{}]|(?1))*+\}))#"; 
$str = "Hello {#name}! I'm a {%string|sentence|bit of {#random} text}"; 
preg_match_all($re, $str, $matches, PREG_OFFSET_CAPTURE);
print_r($matches[1]);

请参阅IDEONE demo

它将返回一个包含捕获的{...}字符串及其位置的数组:

Array
(
    [0] => Array
        (
            [0] => {#name}
            [1] => 6
        )

    [1] => Array
        (
            [0] => {%string|sentence|bit of {#random} text}
            [1] => 21
        )

    [2] => Array
        (
            [0] => {#random}
            [1] => 46
        )

)