regex之如何用 Perl 正则表达式替换字符串中的最后一次出现
好的,这是我的测试(这不是生产代码,只是为了说明我的问题的测试)
my $string = <<EOS; # auto generated query
SELECT
users.*
, roles.label AS role_label
, hr_orders.position_label
, deps.label AS dep_label
, top_deps.label AS top_dep_label
FROM
users
LEFT JOIN $conf->{systables}->{roles} AS roles ON users.id_role = roles.id
LEFT JOIN (
SELECT
id_user
, MAX(dt) AS max_dt
FROM
hr_orders
WHERE
fake = 0
AND
IFNULL(position_label, ' ') <> ' '
GROUP BY id_user
) last_hr_orders ON last_hr_orders.id_user = users.id
LEFT JOIN hr_orders ON hr_orders.id_user = last_hr_orders.id_user AND hr_orders.dt = last_hr_orders.max_dt
$join
WHERE
$filter
ORDER BY
$order
$limit
EOS
my $where = "WHERE\nusers.fake = -1 AND ";
$string =~ s{where}{$where}i;
print "result: \n$string";
生成查询的代码以简单的 s{where}{$where}i 结尾,它替换了所有出现的 where。
我想用“WHERE users.fake = -1”替换顶级 WHERE(WHERE 的最后一次出现?)(实际上,使用更复杂的模式,但这并不重要)。
有什么想法吗?
请您参考如下方法:
为什么要通过对字符串进行硬编码然后对其进行替换来构建 sql 查询?不会像
my $proto_query = <<'EOQ'
select ... where %s ...
EOQ
my $query = sprintf $proto_query, 'users.fake = -1 AND ...';
或者(最好是,因为它避免了您最初的方法和上面的方法的很多问题)使用诸如 Data::Phrasebook::SQL 之类的模块让很多事情变得更容易?
如果你真的想进行字符串替换,你可能正在寻找类似的东西
my $foo = "foo bar where baz where moo";
$foo =~ s/(.*)where/$1where affe and/;
say $foo; # "foo bar where baz where affe and moo"
也就是说,尽可能多地捕获,直到您不能再捕获,而没有立即跟随您捕获的内容的“位置”,然后插入您再次捕获的捕获的内容,以及您想要进行的任何修改。
但是,请注意,如果您使用它来处理 SQL 查询,它会有各种限制。要正确地做事,您必须在某种程度上真正理解 SQL。例如,考虑 select ... where user.name = 'where'。
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。



