Oracle正则表达式用字母替换数字

时间:2019-08-29 04:05:06

标签: sql oracle replace oracle12c regexp-replace

我有一个仅包含数字的字符串。 我需要将字符串中的所有数字替换为以下对应的字母,

0   ->  A
1   ->  B
2   ->  C
..
9   ->  J

我在下面尝试使用翻译和替换功能,对我来说很好用

Forward :
    WITH T (ID) AS (SELECT '10005614827' FROM DUAL)
    SELECT ID, TRANSLATE(ID,'0123456789','ABCDEFGHIJ')  "TRANSLATE",
           REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ID,'0','A'),'1','B'),'2','C'),'3','D'),'4','E'),'5','F'),'6','G'),'7','H'),'8','I'),'9','J') "REPLACE"
    FROM T;

    Output:
        ID          TRANSLATE       REPLACE
        10005614827 BAAAFGBEICH     BAAAFGBEICH

Reverse:
    WITH T (ID) AS (SELECT 'BAAAFGBEICH' FROM DUAL)
    SELECT ID, TRANSLATE(ID,'ABCDEFGHIJ','0123456789')  "TRANSLATE",
           REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(ID,'A','0'),'B','1'),'C','2'),'D','3'),'E','4'),'F','5'),'G','6'),'H','7'),'I','8'),'J','9') "REPLACE"
    FROM T;

    Output:
        ID          TRANSLATE       REPLACE
        BAAAFGBEICH 10005614827     10005614827

有没有办法使用正则表达式来实现这一点?

WITH T (ID) AS (SELECT '10005614827' FROM DUAL)
SELECT ID, REGEXP_REPLACE(ID,'[0-9]','[A-J]')
FROM T;

2 个答案:

答案 0 :(得分:1)

由于当前实施的限制,在Oracle中是不可能的。

更具体地说,您不能将函数应用于匹配值,只能使用\ n形式的反向引用,其中n是1到9之间的数字。

例如,您可以匹配每个数字,并重复等于的次数。

column example format a40
with t(id) as (select '10005614827' from dual)
select id,
regexp_replace(id,'(1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)|(0)','\1\2\2\3\3\3\4\4\4\4\5\5\5\5\5\6\6\6\6\6\6\7\7\7\7\7\7\7\8\8\8\8\8\8\8\8\9\9\9\9\9\9\9\9\9') example          
from t
/


ID          EXAMPLE                                 
----------- ----------------------------------------
10005614827 1555556666661444488888888227777777      
1 row selected.

但是您不能在\ n替换字符串中应用任何功能。

另一方面,在Perl,Java,Scala等语言中,甚至在PowerShell和其他语言中,它都是可行的。

Scala REPL中的示例。

scala>   val str = "10005614827"
str: String = 10005614827

scala>   // matching and converting each digit separately

scala>   "\\d".r.replaceAllIn(str, x => (x.group(0)(0)+17).toChar + "")
res0: String = BAAAFGBEICH

scala>   // marching and converting sequences of digits

scala>   "\\d+".r.replaceAllIn(str, x => x.group(0).map(x=>(x+17).toChar))
res1: String = BAAAFGBEICH

要完成图片,请为娱乐建模模型。

SQL> with t(id) as (select '10005614827' from dual)
  2  select *
  3  from t
  4  model partition by (id) dimension by (0 i) measures (id result)
  5  rules iterate(10)
  6  (result[0] = replace(result[0],iteration_number,chr(ascii(iteration_number)+17)))
  7  /

ID                   I RESULT
----------- ---------- -----------
10005614827          0 BAAAFGBEICH
在这种情况下,

translate是最好的方法。这正是此功能的目的。

PS。例如,上面的Scala等效项,其功能是应用于匹配值,而不是使用反向引用。

"\\d".r.replaceAllIn(str, x => (x.group(0)*(x.group(0)(0)-48)))

答案 1 :(得分:0)

使用翻译功能,我看不到问题。 例如,字符串号为'3389432543'的您可以使用

进行转换
         SELECT TRANSLATE('3389432543','0123456789','ABCDEFGHIJ')
         FROM DUAL;