【问题标题】:Regex to format IPv6 address - remove leading zeroes正则表达式格式化 IPv6 地址 - 删除前导零
【发布时间】:2015-12-04 11:27:03
【问题描述】:

假设我有一个 IPv6 地址,例如:

2001:04E8:0000:4001:0000:0000:0000:0000/64

我想要像这样的输出

2001:4E8:0:4001:0:0:0:0/64

所以基本上,它会删除前导零,同时用一个零替换四个零。

replaceAll("(:(0)*)|(^0+)",":")

上面的正则表达式完成了这项工作,但输出为

2001:4E8::4001::::/64

四个零都省略了。

注意:输入可能是任何有效的 ipv6 地址

【问题讨论】:

  • 您使用的是哪个 dbms?产品之间的替换/正则表达式功能往往会有所不同。

标签: sql regex oracle


【解决方案1】:

您可以使用REPLACE 两次和SUBSTR 删除前导0。

SELECT ipv6,
       SUBSTR(REPLACE(REPLACE(':' || ipv6, ':00', ':'),':0', ':'),2) AS result
FROM tab;

SqlFiddleDemo

演示正在使用MySQL,因为Oracle 没有响应。唯一的变化是字符串连接。

输出:

╔═════════════════════════════════════════════╦════════════════════════════╗
║                    ipv6                     ║           result           ║
╠═════════════════════════════════════════════╬════════════════════════════╣
║ 2001:04E8:0000:4001:0000:0000:0000:0000/64  ║ 2001:4E8:0:4001:0:0:0:0/64 ║
║ 0000:0001:0012:0123:1234:0000:0000:0000/64  ║ 0:1:12:123:1234:0:0:0/64   ║
║ 0001:04E8:0000:4001:0000:0000:0000:0000/64  ║ 1:4E8:0:4001:0:0:0:0/64    ║
║ 0012:04E8:0000:4001:0000:0000:0000:0000/64  ║ 12:4E8:0:4001:0:0:0:0/64   ║
║ 0123:04E8:0000:4001:0000:0000:0000:0000/64  ║ 123:4E8:0:4001:0:0:0:0/64  ║
╚═════════════════════════════════════════════╩════════════════════════════╝

【讨论】:

    【解决方案2】:

    使用 Oracle 的 Regexp_Replace 的示例:

       SQL> with t as (
      2  select '2001:04E8:0000:4001:0000:0000:0000:0000/64' str from dual union all
      3  select '0000:0001:0012:0123:1234:0000:0000:0000/64' from dual union all
      4  select '0001:04E8:0000:4001:0000:0000:0000:0000/64' from dual union all
      5  select '0000:0001:0012:0123:1234:0000:0000:0000/64' from dual
      6  ) -- end of sample data
      7  select regexp_replace(str, '(:|^)(0{0,3})([1-9]*)', '\1\3') str
      8    from t;
    STR
    --------------------------------------------------------------------------------
    2001:4E8:0:4001:0:0:0:0/64
    0:1:12:123:1234:0:0:0/64
    1:4E8:0:4001:0:0:0:0/64
    0:1:12:123:1234:0:0:0/64
    

    【讨论】:

    • 我喜欢这个解决方案,我看到的唯一问题是当输入类似于 '2001:04E8:0000:4001:0000:0:0000:0/64' 时输出将是 '2001:04E8:0000 :4001:0::0:/64'
    【解决方案3】:

    在 java 中,这样的工作:

    replaceAll("(:000)|(:0*)", ":");
    

    【讨论】:

      【解决方案4】:

      试试这个:

      WITH t AS (
        SELECT '2001:04E8:0000:4001:0000:0000:0000:0000/64' str FROM dual UNION ALL
        SELECT '0000:0001:0012:0123:1234:0000:0000:0000/64' FROM dual UNION ALL
        SELECT '0001:04E8:0000:4001:0000:0000:0000:0000/64' FROM dual UNION ALL
        SELECT '0000:0001:0012:0123:1234:0000:0000:0000/64' FROM dual UNION ALL
        SELECT '2001:04E8:0000:4001:0000:0:0000:0/64' FROM dual
        )
      SELECT 
          REGEXP_REPLACE(str, '(:|^)0+([[:xdigit:]]+)', '\1\2')
      from t;
      
      2001:4E8:0:4001:0:0:0:0/64
      0:1:12:123:1234:0:0:0/64
      1:4E8:0:4001:0:0:0:0/64
      0:1:12:123:1234:0:0:0/64
      2001:4E8:0:4001:0:0:0:0/64
      

      【讨论】:

        猜你喜欢
        • 2014-01-27
        • 2013-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-28
        • 1970-01-01
        • 2011-09-11
        相关资源
        最近更新 更多