2

只是在做一个简单的模式匹配。虽然下面以某种方式返回了我想要的。它不是我想要的方式。例如结果输出:

一二三()

而不是我想要的:one();two();three()

不知道为什么它忽略了 ; 的内爆分隔符。返回结果时。也不是为什么它在下一行包含“一个”这个词。它应该只匹配其列表中的单词,并添加检查以查看该单词是否使用 ()。因此留下诸如“一”“二”“三”之类的词。然而匹配 'one()' 或 'one(somestuff)'。

我在 preg_match_all 中使用了 # 作为分隔符。新线 $str 的回声,使其不会在此网站上创建滚动条。使用 echo 来格式化结果不会出现在最终代码中。只是使用它们来查看代码是如何返回的。

非常感谢任何有关如何解决此问题的帮助。我可能在代码方面有点愚蠢。

在“编辑 2”上。如果它可以作为更好的理解。我试图弄清楚如何捕获可能传递给 eval 的命令和/或函数。我正在尝试设计一个扫描“函数 val1(val2)”或“val1(val2)”的正则表达式。这也将合并 'val1' 和 '(val2)' 之间的任何空格。确定它是否是实际的命令/功能。据我所知,你可以做一些类似'die("die")' 或'die ("die")' 的事情。希望它在空白处合并两个单词,然后进行评估。仍在玩耍,试图为自己弄清楚这一点,并阅读。'Edit 2' 也匹配了大部分单词,但没有捕捉到所有单词。我也不希望它使 ) 作为表达式的可选匹配项。IE 它将匹配 'val1(val2)' 和 'val1 (val2)' ,当甚至可能没有任何东西要检查时。然后仅在遇到时针对白名单运行看到的潜在命令。这样用户提交'$you =“你好吗”;' 将通过评估权。而 'me($you)' 将被捕获并根据白名单进行评估。当甚至可能没有任何东西要检查时。然后仅在遇到时针对白名单运行看到的潜在命令。这样用户提交'$you =“你好吗”;' 将通过评估权。而 'me($you)' 将被捕获并根据白名单进行评估。

简单地说:要扫描潜在的命令 - 即“val1(val2)”,将其与白名单进行检查,然后对其进行评估。只有系统命令会被列入白名单。用户命令将被拒绝。即“preg_match_all”与用户创建的“myfunc”。

echo $str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
            echo \$you; \$t = \"one() two() three()\"; ";

if (preg_match_all('#(one|two|three)\(.*\)#i',$str,$m)){
    echo "\n---\n";
        foreach ($m as $k => $v){
            echo $k . "=" . implode(";",$v)."\n";
        }
    echo "---\n";
}

编辑 1:

$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you;
       echo \$us; echo \$you; \$t = \"one(two) two(1) three(2one)\"; ";

preg_match_all('#((one|two|three)\([\s\S]*?\))#i',$str,$m);
$t = implode(';',$m[1]);
if ($t != null))echo $t;
else echo "empty";

编辑 2:

$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
       echo \$you; \$t = \"eval($me)  one($two) two($1) three($2one)}meme1(you2) 
       this(that) die (\"meohmy\") function myfunc($me) empty() \"; ";

preg_match_all('#(([\w+]*)\([\s\S]*?\))#i',$str,$m);
    $t = implode(';',$m[1]);
        if ($t != null){
            echo $t;
            // check a whitelist for allowed commands vs ones captured here
        }else eval($str);

未命中:'死(“meohmy”)'

匹配:'die($this)' 和 'die($this'。而不是只匹配 'die($this)' 而忽略 'die($this'。


编辑3:

$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
       echo \$you; \$t = \"eval($me)  one($two) two($1) three($2one)}meme1(you2) 
       this(that) die (\"meohmy\") these function myfunc($me) empty()\"; ";

$cmd = preg_match_all('#(([\w+])*([\s\S])\([\s\S]*?\))#i',$str,$m);
$t = implode(';',$m[1]);
    if ($t != null){
        echo "Result : " . $t . " [" . $cmd . "]\n";
        // check a whitelist for allowed commands vs ones captured here
    }else eval($str);

匹配:具有畸形结构的潜在命令。即'this($one that($one)'返回'this($one that($one)'。而不是只返回'that($one)'并排除'this($one'。到底哪个是'不是很关键,因为它会返回一个未列在白名单上的匹配项。并且 eval 的执行将停止。


编辑4:

有关包含的代码,请参见上文。仅提供正则表达式。

$cmd = preg_match_all('#(\w*)\s*\(.*?\)#i',$str,$m);

位更清洁的回报:完全匹配数组和单词数组。尽管仍在研究如何让它在格式错误的比赛中停止。即匹配'func(val1)'但不包括'func(val1'。因为它不是正确的模式。目前正则表达式将匹配'func(val1 somefunc(val2)'。因为它只注意到它没有命中')'在第一场比赛上。所以它会扫描直到匹配,然后将它们全部啮合在一起。而不是看到它的格式错误并排除它。

想法:我读到的很多内容都指出,在 eval 之前,通过正则表达式为函数解析字符串是无效的。并且应该明确调用所需的功能。我认为这些人可能已经忘记了function_exists。或者比我的设计更好的正则表达式。可以有效地整理数据以传递给 function_exists。希望能及时让我的正则表达式变得比现在更好。所以最终的想法是。正则表达式函数的字符串,整理它们,然后使用 function_exists 扫描它们。然后毕竟,也许是消毒,评估它。

示例返回:eval($me) 将输出到两个数组中:eval($me) 和 eval。

我的编辑应该表明我很乐意提供帮助。虽然我也在努力为自己弄清楚。所以不仅仅是你能为我做的问题=)。我寻求理解,这样我就可以为自己做点什么。

输入 :

eval($me) one($two) two($1) three($2one)}meme1(you2) this(that) die (\"meohmy\") function myfunc($me Holycrackers batman empty()

输出:

array (
  0 => 
  array (
    0 => 'eval($me)',
    1 => 'one($two)',
    2 => 'two($1)',
    3 => 'three($2one)',
    4 => 'meme1(you2)',
    5 => 'this(that)',
    6 => 'die   (\\"meohmy\\")',
    7 => 'myfunc($me holycrackers batman empty()',
  ),
  1 => 
  array (
    0 => 'eval',
    1 => 'one',
    2 => 'two',
    3 => 'three',
    4 => 'meme1',
    5 => 'this',
    6 => 'die',
    7 => 'myfunc',
  ),
)
4

1 回答 1

1

我不确定我的问题是否正确,但这是你所期望的吗?

<?php
$str = " \$me = \"me\"; \$you = \"you\"; \$us = \$me . \$you; echo \$us;
            echo \$you; \$t = \"one() two() three()\"; ";
$matches = array();
preg_match_all('/((one|two|three)\([\s\S]*?\))/i',$str,$matches);

echo implode(';',$matches[1]);
于 2013-03-25T09:15:25.683 回答