一种很小的模板语言

时间:2015-08-30 17:54:12

标签: regex perl parsing

我传给一个带有"部分" SQL语句如:

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

然后我想用一个真实的字段列表(我从数组中获取)或%FIELDS%替换COUNT(*)。同样,我将%ORDER%替换为ORDER BY ...(我生成)或使用空字符串%LIMIT%替换为LIMIT ...(我生成)或空字符串。

我还想要一种方法来防止这些序列被替换。例如,我们可能会关闭"如果百分比加倍,则替换:%%FIELDS%%不应替换为字段列表,而应替换为文字%FIELDS%

请注意,我并不坚持这种语法。我们可以使用其他一些转义语法(例如${FIELDS}{{FIELDS}})来代替百分号。

我希望最简单和(可能更重要)最有效的方法。

请注意,我使用的是Perl。

也许,我不应该用regexp创建自己的模板语言并使用Perl模块Template::Tiny?什么是最有效的?

1 个答案:

答案 0 :(得分: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";