我可以对REGEXP_REPLACE
后向引用值使用一些函数调用吗?
例如,我想对后向引用值调用chr()
或任何其他函数,但这
SELECT REGEXP_REPLACE('a 98 c 100', '(\d+)', ASCII('\1')) FROM dual;
仅返回ASCII值“ \”:
'a 92 c 92'
我希望最后一个参数(替换字符串)首先被求值,然后替换字符串。因此结果将是:
'a b c d'
答案 0 :(得分:1)
使用一个正则表达式执行此操作并不聪明,但是-分步执行,类似这样的操作可能会有所帮助。它将源字符串分成几行,检查部分字符串是否为数字,如果是,则选择其中的SELECT
A,
B,
LAG(A,1) OVER(ORDER BY B) AS NextA
FROM
foo;
。最后,所有内容都聚合回到单个字符串。
CHR
可以将其缩短一步(我有意将其保留为 ,这样您就可以一次执行一个查询并检查结果,以使事情更清楚):
SQL> with test (col) as
2 (select 'a 98 c 100' from dual),
3 inter as
4 (select level lvl,
5 regexp_substr(col, '[^ ]+', 1, level) c_val
6 from test
7 connect by level <= regexp_count(col, ' ') + 1
8 ),
9 inter_2 as
10 (select lvl,
11 case when regexp_like(c_val, '^\d+$') then chr(c_val)
12 else c_val
13 end c_val_2
14 from inter
15 )
16 select listagg(c_val_2, ' ') within group (order by lvl) result
17 from inter_2;
RESULT
--------------------
a b c d
SQL>
[编辑:如果输入看起来不同怎么办?]
那有点简单。使用SQL> with test (col) as
2 (select 'a 98 c 100' from dual),
3 inter as
4 (select level lvl,
5 case when regexp_like(regexp_substr(col, '[^ ]+', 1, level), '^\d+$')
6 then chr(regexp_substr(col, '[^ ]+', 1, level))
7 else regexp_substr(col, '[^ ]+', 1, level)
8 end c_val
9 from test
10 connect by level <= regexp_count(col, ' ') + 1
11 )
12 select listagg(c_val, ' ') within group (order by lvl) result
13 from inter;
RESULT
--------------------
a b c d
SQL>
提取数字:REGEXP_SUBSTR
返回第一个数字,..., 1, 1
返回第二个数字。纯... 1, 2
然后用数字REPLACE
替换数字。
CHR
答案 1 :(得分:1)
只是为了好玩,您可以使用XPath进行标记化,将数字转换为字符并进行聚合:
select *
from xmltable(
'string-join(
for $t in tokenize($s, " ")
return if ($t castable as xs:integer) then codepoints-to-string(xs:integer($t)) else $t,
" ")'
passing 'a 98 c 100' as "s"
);
Result Sequence
--------------------------------------------------------------------------------
a b c d
初始字符串值作为$s
传递; tokenize()
使用空格作为分隔符将其拆分;对每个生成的$t
进行评估,看是否是整数,然后通过codepoints-to-string
将其转换为等效字符,否则将其保留;然后将所有令牌与string-join()
重新组合。
如果原件上有多个空格,则它们会折叠成一个空格(就像使用Littlefoot的正则表达式一样)。