3

我正在用 PHP 开发一个解析器,我需要一个功能正则表达式来验证包含函数的字符串。

只是为了理解,我将考虑使用preg_replace_callbackcreate_function执行该函数并递归地替换字符串中的值;

字符串示例:15 + func1 ("gis", 22, func (55), 87) + 95 + func2 () + 35

正则表达式应该能够结合所有功能func1并加入func 2。正则表达式仅作为函数(([^ ()])+([ ]?)*\(.*\))*输出。func1 ("gis", 22, func (55), 87) + 95 + func2 ()这是错误的,因为“95”没有任何功能。正则表达式还必须能够处理函数,例如 func1 中的角色。

感谢任何帮助。

4

2 回答 2

2

考虑使用 PHP 的内置标记器,而不是使用正则表达式:

http://www.php.net/manual/en/function.token-get-all.php

$tokens = token_get_all('<?php 15 + func1 ("gis", 22, func (55), 87) + 95 + func2 () + 35; ');

这将返回一个解析器标记数组,您可以使用这些标记将函数与其参数匹配。

于 2013-06-15T20:19:54.043 回答
1

你可以试试这个:

$subject = '15 + func1 ("gis", 22, func (55), 87) + 95 + func2 () + 35';

$pattern = <<<'LOD'
~
 #definitions:

 (?(DEFINE)(?<int>     [0-9]++        ))
 (?(DEFINE)(?<str>     "[^"]++"       ))

 (?(DEFINE)(?<f_name>  \b[a-z]\w*+\b  ))
 (?(DEFINE)(?<sep>     ,\h            ))

 #pattern:

 (?=
     (
        (?<func>\g<f_name>) \s*+
        \( 
           (?<args>
             (?> (?> \g<int> | \g<str> | (?-3) ) \g<sep>?+ )*
           )
        \) 
     )
 )
~x
LOD;

preg_match_all($pattern, $subject, $matches);

print_r($matches['func']);
print_r($matches['args']);

这个想法是使用递归来匹配函数内部的函数,并将所有模式放在一个前瞻中以捕获所有重叠的参数。

请注意,我使用递归(?-3)来引用左侧的第三个捕获组,这是模式的第一组,因此您可以将其替换为(?1). 但是,如果您想将此模式用作子模式,则相对引用可能很有用。

(?(DEFINE)..)注释模式(x 修饰符)结合使用可能很有用,因为它是高度可编辑的,您可以添加或编辑数据类型或解析器可能遇到的其他元素。例如,如果您想允许单引号之间的字符串,您可以<str>像这样更改子模式:

(?(DEFINE)(?<str>     "[^"]++" | '[^']++'    ))

或者像这样更宽容(允许转义引号)

(?(DEFINE)(?<str>     "(?>[^"]++|(?<=\\)")++" | '(?>[^']++|(?<=\\)')++'  ))
于 2013-06-15T20:31:33.597 回答