我正在研究逆向工程PHP方法,因为提供的\ ReflectionClass机制不足以支持我当前的项目。
目前我想使用正则表达式方法原型。我无法检索默认参数值。我正在提供静态方法MethodArgs :: createFromString()以及方法原型括号的内容。它的目标是从字符串中获取所有参数,包括参数类型,名称...和默认值,并创建自身的实例。到目前为止,我已经能够成功检索字符串的单引号和双引号的默认值,包括例如'\''或“\”的特殊情况。但PHP接受默认参数值的标量值范围有点大我在扩展我的正则表达式时遇到问题,以匹配布尔值,整数,浮点数或数组等类型。
<?php
class MethodArgs
{
static public function createFromString($str) {
$str = " Peer \$M = null, Template \$T='variable \'value', \BlaBla\Bla \$Bla = \" blablabla \\\" bleble \" ";
//$pat = '#(?:(?:\'|")(?<val>(?:[^\'"]|(?<=\\\)(?:\'|"))*)(?:\'|"))+#i';
//$pat = '#(?:(?<type>[^\$\s,\(\)]+)\s)?\$(?<name>[^,.\s\)=]+)(?:\s*=\s*)?(?:\'(?<val>(?:[^\']|(?<=\\\)\')*)\')?#i';
$pat = '#(?:(?<type>[^\$\s,\(\)]+)\s)?\$(?<name>[^,.\s\)=]+)(?:\s*=\s*)?(?:(?:\'|")(?<val>(?:[^\'"]|(?<=\\\)(?:\'|"))*)(?:\'|"))?#i';
$a = preg_match_all($pat, $str, $match);
var_dump(array('$a' => $a, '$pat' => $pat, '$str' => $str, '$match' => $match));
die();
/*$Args = new static();
for($i=0; $i<count($match[0]); $i++) {
$Arg = new MethodArg();
$Arg->setType($match['type'][$i]);
$Arg->setName($match['name'][$i]);
$Arg->setDefaultValue($match['val'][$i]);
$Args[] = $Arg;
}
return $Args;*/
}
}
输出(screenshot):
Array ( [$a] => 3 [$pat] => #(?:(?[^\$\s,\(\)]+)\s)?\$(?[^,.\s\)=]+)(?:\s*=\s*)?(?:(?:'|")(?(?:[^'"]|(? Peer $M = null, Template $T='variable \'value', \BlaBla\Bla $Bla = " blablabla \" bleble " [$match] => Array ( [0] => Array ( [0] => Peer $M = [1] => Template $T='variable \'value' [2] => \BlaBla\Bla $Bla = " blablabla \" bleble " ) [type] => Array ( [0] => Peer [1] => Template [2] => \BlaBla\Bla ) [1] => Array ( [0] => Peer [1] => Template [2] => \BlaBla\Bla ) [name] => Array ( [0] => M [1] => T [2] => Bla ) [2] => Array ( [0] => M [1] => T [2] => Bla ) [val] => Array ( [0] => [1] => variable \'value [2] => blablabla \" bleble ) [3] => Array ( [0] => [1] => variable \'value [2] => blablabla \" bleble ) ) )
〜提前感谢任何建议
答案 0 :(得分:1)
如果您尝试解析单引号或双引号字符串,则应该完成 分两步走验证,然后解析值。
您可以使用\G
锚点在单个正则表达式中执行这两个操作
使用\A\G
进行验证并仅使用\G
进行解析。
如果您确定其有效,则可以跳过验证 以下是两部分(如果需要可以组合) 请注意,它使用un-rolled loop方法解析单引号或双引号 这很快。
验证:
# Validation: '~^(?s)[^"\']*(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"|\'[^\'\\\]*(?:\\\.[^\'\\\]*)*\'|[^"\'])*$~'
^
(?s)
[^"']*
(?:
"
[^"\\]*
(?: \\ . [^"\\]* )*
"
|
'
[^'\\]*
(?: \\ . [^'\\]* )*
'
|
[^"']
)*
$
解析:
# Parsing: '~(?s)(?|"([^"\\\]*(?:\\\.[^"\\\]*)*)"|\'([^\'\\\]*(?:\\\.[^\'\\\]*)*)\')~'
(?s) # Dot all modifier
(?| # Branch Reset
"
( # (1), double quoted string data
[^"\\]*
(?: \\ . [^"\\]* )*
)
"
| # OR
'
( # (1), single quoted string data
[^'\\]*
(?: \\ . [^'\\]* )*
)
'
)