我需要能够在模式匹配语句中以匹配的模式作为参数调用函数,并使用函数的返回结果来替换匹配的模式。在perl中,可以使用eval函数来执行此操作。以下是perl示例:
test =~ s/(>?,)(d+)/eval q{&sum($1,$2)}/ge;
我如何在Python中做到这一点。谢谢你的帮助。
Python与Perl的eval EXPR
并行也被命名为eval
。
更具体地说,
eval( $code )
相当于
DOLLAR_AT = None # Global var $@
def perl_eval( code ):
try:
DOLLAR_AT = None
return eval( code )
catch BaseException as err:
DOLLAR_AT = err
perl_eval( code )
但你实际上是在问/e
的平行度。这就是允许替换表达式成为Perl表达式的原因。在Python中,通过传递re.sub
的第二个参数的函数可以获得类似的结果。
$test =~ s/(d+)+(d+)/ $1 + $2 /eg;
相当于
test = re.sub( r"(d+)+(d+)", lambda _: str( int( _.group(1) ) + int( _.group(2) ) ), test )
现在,让我们看看您发布的代码。我们在这里不关心$@
,所以的Python等价物
$test =~ s/(>?,)(d+)/ eval q{sum( $1, $2 )} /ge;
是
import re
def replacer( match ):
try:
return eval( "sum(" + match.group(1) + ", " + match.group(2) + ")" )
except:
return None
test = re.sub( r"(>?,)(d+)", replacer, test )
[缺少:当替换表达式返回None
时,Perl代码段会发出警告。]
也就是说,eval
的这种使用是完全错误的。
因为sum(>,123)
不是有效的Perl,所以Perl片段等效于
$test =~ s/(>)?,(d+)/ defined( $1 ) ? undef : eval { sum( $2 ) } /ge;
或
import re
def replacer( match ):
if match.group(1) is None:
return None
else
try:
return sum( match.group(2) )
except:
return None
test = re.sub( r"(>)?,(d+)", replacer, test )
[缺少:当替换表达式返回None
时,Perl代码段会发出警告。]
[Python与eval BLOCK
的并行是try
。]
这完全没有道理。以下内容可能更接近作者的意图:
$test =~ s/(>?,)(d+)/ sum( $1, $2 ) /ge;
或
import re
test = re.sub( r"(>?,)(d+)", lambda _ : sum( _.group(1), _.group(2) ), test )
可能不是这样。将>,
或,
传递给名为sum
的子似乎不对。但是,如果不知道sum
做了什么以及这个片段应该做什么,我就无法进一步评论。