使用一个正则表达式我不是很聪明,但是 - 一步一步,这样的事情可能会有所帮助。它将源字符串拆分为行,检查它的一部分是否是数字,如果是,则选择其中的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 值替换数字。
SQL> with test (col) as
2 (select 'a98c100e' from dual)
3 select
4 replace(replace(col, regexp_substr(col, '\d+', 1, 1), chr(regexp_substr(col, '\d+', 1, 1))),
5 regexp_substr(col, '\d+', 1, 2), chr(regexp_substr(col, '\d+', 1, 2))) result
6 from test;
RESULT
--------------------
abcde
SQL>