我想向反向引用添加 (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。
知道为什么会这样吗?
最佳答案
问题:求值顺序
我的猜测(而且只是一个猜测,因为问题不是很清楚)是你对函数调用中参数的求值顺序感到困惑,并试图在 backref 上调用函数 value,但求值顺序意味着它在 正则表达式求值之前对 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,然后将其替换回去。这很 WTFy,为什么?
正则表达式是拆分数字的一种方法,但最好的方法通常是模数和余数:
craig=> SELECT 890808 / 10000, 890808 % 10000;
?column? | ?column?
----------+----------
89 | 808
(1 row)
如果您必须使用正则表达式(例如,如果它是混合的字母数字或者如果您的条件不容易用位值表示),您可能想要使用 regexp_split_to_array
。
关于regex - 在 postgresql 中使用函数修改反向引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22887510/