如何修复 perl eval() 中的 'Bareword found' 问题

How to fix 'Bareword found' issue in perl eval()

以下代码 returns“在第 1 行的 (eval 1) 处,在“*,out”(out 之前缺少运算符?)附近的运算符预期位置找到了 Bareword”

$val = 0;
$name = "abc";
$myStr = '$val = ($name =~ in.*,out [)';
eval($myStr);

根据我的理解,我可以通过用 '//' 包装“in.*,out [”块来解决这个问题。

但是“in.*,out [”可以变化。 (例如:用户输入)。并且用户可能会错过给出'//'。因此,还有其他方法可以处理这个问题吗? (例如:return 0 如果 eval() 试图 return 那 'Bareword found where ...')

(string)eval 的魔力——也是危险——在于它将一堆虚拟字符转换为 代码,编译并运行它。那么可以使用 '$x = ,hi' 吗?好吧,不,当然,当那个字符串被认为是代码时,那是一个松散的逗号运算符,一个语法错误;和一个“裸词”hi. 字符串必须产生有效代码

In a string eval, the value of the expression (which is itself determined within scalar context) is first parsed, and if there were no errors, executed as a block within the lexical context of the current Perl program.

因此,问题中的字符串只是(严重)无效代码,无法编译,句号。如果字符串的 in.*,out [ 部分在某种引号中,那么这是合法的,并且 =~ operator 会将其作为模式并且您有一个正则表达式。但是当然为什么不使用正则表达式的正常模式定界符,如 //(或 m{} 等)。

无论以何种方式获取该字符串,它都会在一个变量中,不是吗?因此,您可以在 eval 中包含 /$input/ 并预先填充 $input

但是,最重要的是,您确定没有其他办法吗?总是有。 string-eval 复杂而棘手,难以正确使用,几乎不可能证明其合理性——而且很危险。它运行任意代码!即使没有任何恶意,这也会严重破坏事情。

我强烈建议考虑其他解决方案。此外,目前还不清楚为什么首先需要 eval - 因为你只需要正则表达式模式作为用户输入(而不是代码)你可以在普通代码中使用正则表达式一个变量,在提供用户输入时更早填充。 (请注意,从用户那里获取模式也可能会导致麻烦。)


如果你喜欢warnings,那是个问题,我们都是。

以下是无效的 Perl 代码:

$val = ($name =~ in.*,out [)

您想要以下内容:

$val = $name =~ /in.*,out \[/

(parens 没有害处,但也没有帮助。)

如果模式是user-supplied,你可以使用下面的:

$val = $name =~ /$pattern/

(不需要 eval EXPR!)

从更正中注意到问题中的模式不正确。您可以使用 eval BLOCK

捕获此类错误
eval { $val = $name =~ /$pattern/ };
die("Bad pattern \"$pattern\" provided: $@") if $@;

关于 user-provided 模式的注意事项:以上不会让用户执行任意代码,但它不会保护您免受需要比宇宙生命周期更长的时间才能完成的模式。