我想将(int)值添加到反向引用中。
为此我创建了一个函数并传递了适当的反向引用。如果在没有任何修改的情况下返回的反向引用工作正常,但是当我尝试修改或使用传递的反向引用上的任何其他函数时,它假定\ 3作为参数值而不是反向引用值本身。
例如 -
CREATE OR REPLACE FUNCTION add10(text) returns text as $$
DECLARE
t int;
BEGIN
t := to_number($1, '999999') + 10;
return trim(to_char(t, '999999'), ' ');
END;
$$ LANGUAGE plpgsql;
然后:
select regexp_replace('890808', '80(\d+)', add10('\1'), 'g');
应该给出结果
test
-------
89018
(1 row)
然而它给出了 -
test
-------
89011
(1 row)
将$ 1的值作为1(反向引用号)而不是值8。
为什么会发生这种情况?
答案 0 :(得分:1)
我的猜测(只是猜测,因为问题不是很清楚)是你对函数调用中参数的评估顺序感到困惑,并试图调用一个函数backref 值,但评估顺序意味着它在 regexp评估之前在backref字符串上调用。
假设add10
和t
是相同的,那么:
select regexp_replace('890808', '80(\d+)', add10('\1'), 'g');
通过首先调用add10('\1')
进行评估。那将反过来运行:
select to_number('\1', '999999') + 10 into t;
由于select to_number('\1', '999999')
产生的值为1
,因此您11
会获得t
。然后你将它转换回一个字符串(通过一种相当奇怪的方法,为什么你没有把它转换成它)。
因此,您已将'\1'
替换为'11'
,因此您的regexp_replace
电话似乎如下:
select regexp_replace('890808', '80(\d+)', '11`, 'g');
...您可以从中看到意外结果的来源。
我认为你想要的结果没有任何意义,所以我无法弄清楚如何制作它。你似乎试图在" 80"之前保留所有数字,丢弃" 80",转换" 80"之后的所有数字。一个数字并加上10,然后将其替换回来。这很漂亮,为什么?
正则表达式是分割数字的一种方法,但最好的方法通常是模数和余数:
craig=> SELECT 890808 / 10000, 890808 % 10000;
?column? | ?column?
----------+----------
89 | 808
(1 row)
如果您必须使用正则表达式(例如,如果它是混合的字母数字或者您的条件不容易用地方值表示),您可能想要使用regexp_split_to_array
。