Perl 5.8
在现有的Perl脚本中对相当简单的字符串替换的改进。
代码的意图很明确,代码正在运行。
对于给定的字符串,用一个空格替换每个出现的TAB,LF或CR字符,并用两个双引号替换每个双引号。这是现有代码的片段:
# replace all tab, newline and return characters with single space
$val01 =~s/[\t\n\r]/ /g;
$val02 =~s/[\t\n\r]/ /g;
$val03 =~s/[\t\n\r]/ /g;
# escape all double quote characters by replacing with two double quotes
$val01 =~s/"/""/g;
$val02 =~s/"/""/g;
$val03 =~s/"/""/g;
问题:有没有更好的方法来执行这些字符串操作?
通过“更好的方式”,我的意思是更有效地执行它们,避免使用正则表达式(可能使用tr///
替换tab,换行符和lf字符),或者可能使用({{1避免重新编译。
注意:我已经考虑将字符串操作操作移动到子例程,以减少正则表达式的重复。
注意:此代码有效,但并未真正破解。我只是想知道是否有更合适的编码约定。
注意:这些操作是在循环中执行的,大量(> 10000)迭代。
注意:此脚本目前在perl v5.8.8下执行。 (该脚本有qr//
,但可以更改为require 5.6.0
。(安装更高版本的Perl目前不是生产服务器上的选项。)
require 5.8.8
答案 0 :(得分:3)
您现有的解决方案对我来说很好。
至于避免重新编译,你不必担心。 Perl的正则表达式只按原样编译一次,除非它们包含内插表达式,而不包含内插表达式。
为了完整起见,我应该提一下,即使存在插值表达式,也可以告诉Perl仅通过提供/o
标志来编译正则表达式。
$var =~ s/foo/bar/; # compiles once
$var =~ s/$foo/bar/; # compiles each time
$var =~ s/$foo/bar/o; # compiles once, using the value $foo has
# the first time the expression is evaluated
答案 1 :(得分:2)
答案 2 :(得分:2)
您可能过早地进行了优化。您是否尝试使用Devel::NYTProf等分析器查看您的计划花费大部分时间的费用?
答案 3 :(得分:2)
我的猜测是,tr///
会比第一个正则表达式中的s///
(稍微)快一些。当然,速度要快多少取决于我不了解你的程序和环境的因素。分析和基准测试将回答这个问题。
但是,如果您对代码的任何改进感兴趣,我可以建议可维护性修复吗?您对三个变量运行相同的替换(或替换集)。这意味着当你改变那个替换时,你需要改变它三次 - 做同样的事情三次总是危险的:)
您可以考虑重构代码,使其如下所示:
foreach ($val01, $val02, $val03) {
s/[\t\n\r]/ /g;
s/"/""/g;
}
此外,将这些值放在数组中而不是三个类似命名的变量可能是个好主意。
foreach (@vals) {
s/[\t\n\r]/ /g;
s/"/""/g;
}