2015-08-30 48 views
1

我傳遞一個字符串,如「部分」 SQL語句:一個微小的模板語言

"SELECT %FIELDS% FROM ... %ORDER% %LIMIT%" 

然後我想,以取代%FIELDS%要麼領域(這是我從一個陣列獲得)的實際列表或COUNT(*)。同樣,我將%ORDER%替換爲ORDER BY ...(我生成)或空字符串,%LIMIT%替換LIMIT ...(我生成)或空字符串。

我也想要一種方法來防止這些序列被替換。例如,如果百分數加倍,我們可以「關閉」替換:%%FIELDS%%應該不會被字段列表替換,而應該替換爲字面值%FIELDS%

請注意,我並不堅持這種語法。我們可以使用其他一些轉義語法(例如${FIELDS}{{FIELDS}})代替百分號。

我想要最簡單和(可能更重要)最有效的方法來做到這一點。

請注意,我使用Perl。

也許,我不應該用regexps創建自己的模板語言,並使用Perl模塊Template::Tiny?什麼將是最有效的?

+0

最簡單的方法'$ S =〜S /%FIELDS%/ JOIN( 「」,@ F)/ GE;'應該在這裏工作 –

+0

@HåkonHægland這不支持「我也想辦法以防止這些序列被替換「在我的問題。如果它可以這麼簡單,我不會問這怎麼做 – porton

+0

是的..你是對的..所以在替換'%FIELDS%'後''%ORDER%「'字符串會出現,你不想要以後替換'%ORDER%'時替換? –

回答

0
#!/usr/bin/perl 

use strict; 
use warnings; 

sub MyReplace { 
    my ($tmpl, $Hash) = @_; 

    my %Hash2; 
    foreach my $Key (keys %$Hash) { 
    $Hash2{"%$Key%"} = $Hash->{$Key}; 
    $Hash2{"\\%$Key%"} = "%$Key%"; # escaped 
    } 

    my $re_str = "(" . (join '|', map { "\Q$_\E" } keys %Hash2) . ")"; 
    $tmpl =~ s/$re_str/$Hash2{$1}/g; 
    return $tmpl; 
} 

print MyReplace('SELECT %FIELDS% FROM ... %ORDER% %LIMIT%', {FIELDS=>'a, b, c', ORDER=>'ORDER BY id', LIMIT=>''}), "\n"; 
print MyReplace('SELECT \\%FIELDS% FROM ... %ORDER% \\\\%LIMIT%', {FIELDS=>'a, b, c', ORDER=>'ORDER BY id', LIMIT=>''}), "\n";