捕获所有方法参数默认值 [英] Capturing all method arguments default values

查看:58
本文介绍了捕获所有方法参数默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究反向工程 PHP 方法,因为提供的 \ReflectionClass 机制不足以满足我当前的项目.

I'm working on reverse engineering PHP methods because provided \ReflectionClass mechanism is insufficient for my current project.

目前我想使用正则表达式方法原型.我被困在检索默认参数值上.我提供静态方法 MethodArgs::createFromString() 和方法原型括号的内容.它的目标是从字符串中获取所有参数,包括参数类型、名称...和默认值,并创建它自己的实例.到目前为止,我已经能够成功检索字符串的单引号和双引号的默认值,包括像 '\'' 或 "\"" 这样的特殊情况.但是 PHP 接受的默认参数值的标量值范围有点大. 我在扩展我的正则表达式以匹配布尔值、整数、浮点数或数组等类型时遇到问题.

Currently I want to get using regular expressions method prototypes. I got stuck on retrieving default argument values. I'm providing static method MethodArgs::createFromString() with the contents of method prototype parentheses. It's goal is to get all arguments from string including argument type, name ... and default value and create an instance of itself. So far I've been able to successfully retrieve default values for string's both single quoted and double quoted including exceptional cases like ' \' ' or " \" ". But range of scalar values that PHP accepts for default argument value is a bit larger. I'm having problems extending my regexp to match also types like booleans, integers, floats or arrays.

<?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;*/
    }
}

输出(屏幕截图):

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 
                )

        )

)

~提前感谢您的建议

推荐答案

如果你试图解析单引号或双引号字符串,应该这样做
分两步.验证,然后解析值.

If you are trying to parse single or double quoted strings, it should be done
in two steps. Validation, then parse for values.

您可能可以使用 \G 锚在单个正则表达式中同时执行这两项操作,
使用 \A\G 进行验证并仅使用 \G 进行解析.

You could probably do both in a single regex with the use of a \G anchor,
validating with \A\G and parsing with just the \G.

如果你确定它是有效的,你可以跳过验证.
以下是两部分(如果需要可以组合).
请注意,它使用 un-rolled loop 方法解析单引号或双引号,
这很快.

If you are sure its valid, you can skip the validation.
Below are the two parts (can be combined if needed).
Note that it parses the single or double quotes using the un-rolled loop method,
which is pretty quick.

验证:

 # Validation:  '~^(?s)[^"\']*(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"|\'[^\'\\\]*(?:\\\.[^\'\\\]*)*\'|[^"\'])*$~'

 ^
 (?s)
 [^"']*
 (?:
      "
      [^"\\]*
      (?: \\ . [^"\\]* )*
      "
   |
      '
      [^'\\]*
      (?: \\ . [^'\\]* )*
      '
   |
      [^"']
 )*
 $

解析:

 # Parsing:  '~(?s)(?|"([^"\\\]*(?:\\\.[^"\\\]*)*)"|\'([^\'\\\]*(?:\\\.[^\'\\\]*)*)\')~'

 (?s)                          # Dot all modifier
 (?|                           # Branch Reset
      "
      (                             # (1), double quoted string data
           [^"\\]*
           (?: \\ . [^"\\]* )*
      )
      "
   |                              # OR
      '
      (                             # (1), single quoted string data
           [^'\\]*
           (?: \\ . [^'\\]* )*
      )
      '
 )

这篇关于捕获所有方法参数默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆