【问题标题】:Oracle regular expression to replace numbers with alphabetsOracle正则表达式用字母替换数字
【发布时间】:2020-01-02 07:06:55
【问题描述】:

我有一个只包含数字的字符串。 我需要用下面的相应字母替换字符串中的所有数字,

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;

【问题讨论】:

    标签: sql oracle replace oracle12c regexp-replace


    【解决方案1】:

    使用翻译功能我没有发现问题。 例如,字符串编号“3389432543”可以使用

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

    【讨论】:

    • 您是否设法读到原帖中的至少第三句?
    【解决方案2】:

    由于当前实施的限制,这在 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)))
    

    【讨论】:

    • 感谢@Dr Y Wit 的详细解释
    猜你喜欢
    • 1970-01-01
    • 2019-04-17
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多