捕获所有方法参数默认值
Capturing all method arguments default values
我正在研究逆向工程 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):
数组
(
[$a] => 3
[$pat] => #(?:(?[^\$\s,\(\)]+)\s)?\$(?[^,.\s\)=]+)(?:\ s*=\s*)?(?:(?:'|")(?(?:[^'"]|(? Peer $M = null, Template $T='variable \'value', \BlaBla\Bla $Bla = " blablabla \" bleble "
[$match] => 数组
(
[0] => 阵列
(
[0] => 对等 $M =
[1] => 模板 $T='变量 \'value'
[2] => \BlaBla\Bla $Bla = " blablabla \" bleble "
)
[类型] => 数组
(
[0] => 同行
[1] => 模板
[2] => \BlaBla\Bla
)
[1] => 数组
(
[0] => 同行
[1] => 模板
[2] => \BlaBla\Bla
)
[名称] => 数组
(
[0] => 米
[1] => T
[2] => 布拉
)
[2] => 数组
(
[0] => 米
[1] => T
[2] => 布拉
)
[val] => 数组
(
[0] =>
[1] => 变量\'值
[2] => blablabla \" bleble
)
[3] => 数组
(
[0] =>
[1] => 变量\'值
[2] => blablabla \" bleble
)
)
)
~ 在此先感谢您的任何建议
如果您尝试解析单引号或双引号字符串,应该这样做
分两步。验证,然后解析值。
您可以使用 \G
锚点在一个正则表达式中完成这两项操作,
使用 \A\G
验证并仅使用 \G
进行解析。
如果您确定其有效,则可以跳过验证。
以下是两个部分(如果需要可以合并)。
请注意,它使用展开循环方法解析单引号或双引号,
这是相当快的。
验证:
# Validation: '~^(?s)[^"\']*(?:"[^"\\]*(?:\\.[^"\\]*)*"|\'[^\'\\]*(?:\\.[^\'\\]*)*\'|[^"\'])*$~'
^
(?s)
[^"']*
(?:
"
[^"\]*
(?: \ . [^"\]* )*
"
|
'
[^'\]*
(?: \ . [^'\]* )*
'
|
[^"']
)*
$
正在解析:
# Parsing: '~(?s)(?|"([^"\\]*(?:\\.[^"\\]*)*)"|\'([^\'\\]*(?:\\.[^\'\\]*)*)\')~'
(?s) # Dot all modifier
(?| # Branch Reset
"
( # (1), double quoted string data
[^"\]*
(?: \ . [^"\]* )*
)
"
| # OR
'
( # (1), single quoted string data
[^'\]*
(?: \ . [^'\]* )*
)
'
)
我正在研究逆向工程 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):
数组 ( [$a] => 3 [$pat] => #(?:(?[^\$\s,\(\)]+)\s)?\$(?[^,.\s\)=]+)(?:\ s*=\s*)?(?:(?:'|")(?(?:[^'"]|(? Peer $M = null, Template $T='variable \'value', \BlaBla\Bla $Bla = " blablabla \" bleble " [$match] => 数组 ( [0] => 阵列 ( [0] => 对等 $M = [1] => 模板 $T='变量 \'value' [2] => \BlaBla\Bla $Bla = " blablabla \" bleble " ) [类型] => 数组 ( [0] => 同行 [1] => 模板 [2] => \BlaBla\Bla ) [1] => 数组 ( [0] => 同行 [1] => 模板 [2] => \BlaBla\Bla ) [名称] => 数组 ( [0] => 米 [1] => T [2] => 布拉 ) [2] => 数组 ( [0] => 米 [1] => T [2] => 布拉 ) [val] => 数组 ( [0] => [1] => 变量\'值 [2] => blablabla \" bleble ) [3] => 数组 ( [0] => [1] => 变量\'值 [2] => blablabla \" bleble ) ) )
~ 在此先感谢您的任何建议
如果您尝试解析单引号或双引号字符串,应该这样做
分两步。验证,然后解析值。
您可以使用 \G
锚点在一个正则表达式中完成这两项操作,
使用 \A\G
验证并仅使用 \G
进行解析。
如果您确定其有效,则可以跳过验证。
以下是两个部分(如果需要可以合并)。
请注意,它使用展开循环方法解析单引号或双引号,
这是相当快的。
验证:
# Validation: '~^(?s)[^"\']*(?:"[^"\\]*(?:\\.[^"\\]*)*"|\'[^\'\\]*(?:\\.[^\'\\]*)*\'|[^"\'])*$~'
^
(?s)
[^"']*
(?:
"
[^"\]*
(?: \ . [^"\]* )*
"
|
'
[^'\]*
(?: \ . [^'\]* )*
'
|
[^"']
)*
$
正在解析:
# Parsing: '~(?s)(?|"([^"\\]*(?:\\.[^"\\]*)*)"|\'([^\'\\]*(?:\\.[^\'\\]*)*)\')~'
(?s) # Dot all modifier
(?| # Branch Reset
"
( # (1), double quoted string data
[^"\]*
(?: \ . [^"\]* )*
)
"
| # OR
'
( # (1), single quoted string data
[^'\]*
(?: \ . [^'\]* )*
)
'
)