Perl正则表达式的妙用
时间:2008-06-28 来源:xktop
Perl和正则表达式稍微懂点计算机的都了解,但笔者最近在工作中犯的一个错误却使自己明白了原来Perl的正则表达式还可以这样用。这个错误是这样的,笔者想要把从数据库中pull的数据按照csv的格式输出,分隔符使用vertical bar,但在输出之前,笔者需要保证数据中不包含用作分隔符的vertical bar (否则岂不乱套),所以笔者对每一个数据都进行了替换操作,将vertical bar转换为其他字符,但由于自己一时不慎,将这段代码写成了:
use strict;
use Win32::SqlServer;
open FILE, ">test.txt" or die "Could not open the file file\n";
my $database = ‘***’;
my $sqlhost = 'localhost'; # IP address or hostname
my $user = '***'; # only used for SQL Server Authentication
my $password = '***'; # only used for SQL Server Authentication
my $sqlsrv = Win32::SqlServer::sql_init(undef, undef, undef, $database);
my $result = $sqlsrv->sql("select * from user_groups", ,
Win32::SqlServer::LIST,
Win32::SqlServer::COLINFO_NAMES,
\&callback);
sub callback {
my ($row, $ressetno) = @_;
my $rline;
for $rline(@$row)
{
$rline =~ s#|#/#gs;
}
print FILE join("|", @$row), "\n";
return Win32::SqlServer::RETURN_NEXTROW;
}
不知大家看出来没有,我的本意是将vertical bar替换为slash,但却忘了vertical bar在正则表达式中的特殊性而没有转义,这导致了一个很有意思的结果。进而我试验了如下若干表达式:
$rline =~ s##/#gs;
$rline =~ s#-|#/#gs;
结果依旧证明,匹配操作如果没有正则式等于匹配-呃-什么都没有,两个字符之间什么都没有,第一个字符之前和最后一个字符之后也什么都没有,恩,就是匹配那个,所以输出结果就像:
/a/b/r/o/d/ /k/i/d/ (实际应该是abrod kid,使用s##/#gs)
/j/o/h/n/ /y//d/ (实际应该是john y-d,使用s#-|#/#gs)
这不免让人兴奋,当然也是自己一直以来研究得不够细致,从来没想过这种情况,或者没有深入正则表达式引擎的实现级别去思考问题所致。不过认识到这种功能,以后有些事情就可以更快速或者更技巧的完成了。