捕获所有方法参数默认值

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
           [^'\]*
           (?: \ . [^'\]* )*
      )
      '
 )