以下代码返回“在 (eval 1) 第 1 行,靠近“*,out”的操作符预期位置找到了裸字(out 之前缺少操作符?)”
$val = 0;
$name = "abc";
$myStr = '$val = ($name =~ in.*,out [)';
eval($myStr);
Run Code Online (Sandbox Code Playgroud)
根据我的理解,我可以通过用“//”包装“in.*,out [”块来解决这个问题。
但是“in.*,out [”可以变化。(例如:用户输入)。用户可能会错过给出“//”。因此,还有其他方法来处理这个问题吗?(例如:如果 eval() 尝试返回“在...处找到裸字”,则返回 0)
(string) eval的魔力和危险在于它将一堆虚拟字符转换为代码,编译并运行它。那么可以使用吗\'$x = ,hi\'
?好吧,不,当然,当该字符串被视为代码时,那么它就是一个松散的逗号运算符,这是一个语法错误;和一个“裸词” hi
。\xe2\x80\xa0该字符串必须产生有效的代码
\n\n在字符串 eval 中,首先解析表达式的值(其本身在标量上下文中确定),如果没有错误,则在当前 Perl 程序的词法上下文中作为块执行。
\n
因此,问题中的字符串实际上只是(严重)无效的代码,无法编译。如果in.*,out [
字符串的一部分用某种引号括起来,那么这是合法的,=~
运算符会将其视为模式,并且您有一个正则表达式。但是当然为什么不使用正则表达式的正常模式分隔符,例如//
(或m{}
等)。
无论以哪种方式获取该字符串,它都会位于变量中,不是吗?因此,您可以预先将其/$input/
放入eval
并填充$input
。
但最重要的是,你确定没有其他办法吗?总是有的。该字符串eval
复杂且棘手,很难正确使用,几乎不可能证明其合理性,而且很危险。它运行任意代码!即使没有任何恶意,这也会严重破坏事情。
我强烈建议考虑其他解决方案。另外,目前还不清楚为什么首先需要eval
- 因为您只需要正则表达式模式作为用户输入(而不是代码),您可以在普通代码中使用该正则表达式,并在变量中使用模式,这当提供用户输入时更早填充。(请注意,从用户那里获取模式也可能会导致麻烦。)
\xe2\x80\xa0如果你喜欢的话warnings
,这是一个问题,我们都喜欢。