提问人:yasara malshan 提问时间:10/22/2021 最后编辑:zdimyasara malshan 更新时间:3/24/2022 访问量:231
如何修复 perl eval() 中的“Bareword found”问题
How to fix 'Bareword found' issue in perl eval()
问:
以下代码返回“Bareword found where operator expected at (eval 1) line 1, near ”*,out“ (Missing operator before out?)”
$val = 0;
$name = "abc";
$myStr = '$val = ($name =~ in.*,out [)';
eval($myStr);
根据我的理解,我可以通过用“//”包装“in.*,out [”块来解决这个问题。
但是“in.*,out [”可以是变化的。(例如:用户输入)。因此,有没有其他方法可以处理这个问题。?(例如:如果 eval() 试图返回“Bareword found where ...”,则返回 0)
答:
(字符串)eval 的魔力和危险在于,它将一堆虚拟字符转换为代码,编译并运行它。那么可以使用吗?嗯,不,当然,当该字符串被视为代码时,它就是一个松散的逗号运算符,一个语法错误;和一个“赤裸裸的词”.†该字符串必须生成有效的代码'$x = ,hi'
hi
在字符串求值中,表达式的值(它本身是在标量上下文中确定的)首先被解析,如果没有错误,则在当前 Perl 程序的词法上下文中作为块执行。
因此,问题中的字符串将只是(严重)无效的代码,不会编译,句号。如果字符串的一部分在某种引号中,那么这是合法的,=~
运算符会将其视为一种模式,并且您有一个正则表达式。但是,当然为什么不使用正则表达式的正常模式分隔符,例如(或等)。in.*,out [
//
m{}
无论以何种方式获取该字符串,它都将位于变量中,不是吗?因此,您可以事先将其填充。/$input/
eval
$input
但是,最重要的是,你确定没有其他办法吗?总是有的。字符串 - 复杂而棘手,难以正确使用,几乎不可能证明 - 而且很危险。它运行任意代码!即使没有任何不良意图,也会严重破坏事情。eval
我强烈建议考虑其他解决方案。此外,目前还不清楚为什么首先需要 - 因为你只需要正则表达式模式作为用户输入(而不是代码),你可以在普通代码中拥有非常正则表达式,并在变量中有一个模式,该模式在提供用户输入时会更早填充。(请注意,从用户那里获取模式也可能导致麻烦。eval
†如果你喜欢,这是一个问题,我们都是。warnings
以下代码无效:
$val = ($name =~ in.*,out [)
您需要满足以下条件:
$val = $name =~ /in.*,out \[/
(parens 无害,但也没有帮助。
如果模式是用户提供的,则可以使用以下命令:
$val = $name =~ /$pattern/
(不需要!eval EXPR
请注意,更正中的模式不正确。您可以使用以下命令捕获此类错误eval BLOCK
eval { $val = $name =~ /$pattern/ };
die("Bad pattern \"$pattern\" provided: $@") if $@;
关于用户提供的模式的说明:上面的内容不会允许用户执行任意代码,但它不会保护你免受需要比宇宙寿命更长的模式的伤害。
评论
eval
use warnings;
$myStr
”——问题是,你为什么需要这样做?似乎您可以拥有普通代码,当您接受用户的输入时(可能在程序的前面)将其分配给 。你为什么不能这样做呢?my $val = ($name =~ /$input/);
$input