正则表达式/(ab)?使用/:更复杂的表达值得吗?

dav*_*ave 13 regex perl

我正在编写一个简单的Perl脚本,它将汇编指令字符串转换为32位二进制代码.

我决定按类型处理翻译分组指令(ADD并且SUB是R-Type指令等等)所以在我的代码中我做的是这样的:

my $bin = &r_type($instruction) if $instruction =~ /^(?:add|s(?:ub|lt|gt))\s/;
Run Code Online (Sandbox Code Playgroud)

因为我要处理add,sub,sltsgt以同样的方式.

然而我意识到,使用那个正则表达式对于我应该做的任务可能是一个"过度杀伤"...可能是模式

/^(?:add|sub|slt|sgt)\s/
Run Code Online (Sandbox Code Playgroud)

在这种情况下代表更好地使用正则表达式?

非常感谢.

yst*_*sth 22

除非您使用的是早于5.10的perl,否则简单的替换将无论如何都会表现得更好(参见此处),因此没有理由尝试对其进行优化.


sal*_*lva 5

不要将助记符放在正则表达式中,而是使用哈希构建调度表.它将至少同样更快,您的代码更容易遵循:

my %emitter = (add => \&r_type,
               sub => \&r_type,
               slt => \&r_type,
               sgt => \&r_type,
               ...);

if ($instruction =~ /^(\S+)/) {
    my $emitter = $emitter{$1} // die "bad instruction $instruction";
    $emitter->($1, $istruction);
}
else {
    # error?...
}
Run Code Online (Sandbox Code Playgroud)


bri*_*foy 5

我喜欢salva的调度表(我在Mastering Perl中展示了很多这样的表),但如果你有一天需要针对不同问题的答案,我会回答问题的另一个方面.

当你想构建一些替换,其中一些可能是嵌套时,你可以使用类似Regexp :: Trie的东西为你构建替换,这样你就不会看到丑陋的正则表达式语法:

use Regexp::Trie;
my $rt = Regexp::Trie->new;

foreach ( qw/add sub slt sgt/ ) {
    $rt->add($_);
    }

print $rt->regexp, "\n";
Run Code Online (Sandbox Code Playgroud)

这给你:

 (?-xism:(?:add|s(?:gt|lt|ub)))
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以列出Jonathan建议的操作码,但也可以进行更改.正如你所指出的,无论如何你现在都可以免费使用Perl.