【问题标题】:oracle regexp_replace to remove commas between Quoteoracle regexp_replace 删除引号之间的逗号
【发布时间】:2018-05-30 18:35:09
【问题描述】:

请任何人都可以帮助我。几天来一直在尝试获得一个 regexp_replace 来删除引号之间的逗号,而不管逗号的位置如何。 示例

cold, gold, "Block 12C, Jones Avenue, Broad Street, London", car

预期的答案

cold, gold, "Block 12C Jones Avenue Broad Street London", car

提前致谢

【问题讨论】:

  • 一个字符串中最多有一对双引号吗?
  • 如果引号不止一对,可以嵌套吗?

标签: oracle oracle11g sqlplus


【解决方案1】:

您可以提取双引号 (REGEXP_SUBSTR) 中的内容,替换逗号,然后使用替换将其填充回旧字符串。

select REPLACE (whole_str,quoted_str,REPLACE (quoted_str,',')) FROM
(                
select 
    whole_str, 
    REGEXP_SUBSTR( whole_str, '^[^"]*("[^"]+")',1,1,NULL,1) quoted_str
  FROM yourtable
  );

DEMO

请注意,这也可以使用INSTR,SUBSTR 来完成,这可能更有效,但难以阅读。

【讨论】:

    【解决方案2】:

    您可以使用regexp_replace 来获得所需的输出:

    with t( id , val ) as(
    select 1,'cold, gold, "Block 12C, Jones Avenue, Broad Street, London", car' from dual union
    select 2,'"Block 12C, Jones Avenue, Broad Street, London", car, cold, gold' from dual )
    select id, val value
      from t
     model dimension by( id ) measures( val )
     rules iterate(100)( val[any] = regexp_replace(val[cv()],',(([^"]*"){2})*([^"]*"[^"]*)$',' \1\3') );
    

    d E m O

    【讨论】:

      【解决方案3】:

      我怀疑是否有一个正则表达式函数可以达到预期的结果。 “明显”的攻击路线是将输入字符串切成小块,并根据需要从每个双引号子字符串中删除逗号。 (除非每个字符串最多有一个双引号子字符串,在这种情况下,问题的答案更容易 - 但从示例输入字符串来看,可能需要对具有任意数量的双引号的输入字符串执行相同的操作 -引用的子字符串。)

      这是一个使用递归 WITH 子句的解决方案 - 因此它需要 Oracle 11.2 或更高版本。 (对于早期版本,可以使用带有 CONNECT BY 分层查询的解决方案。)我按照要求使用正则表达式编写了它;如果速度成为问题,可以使用标准的 INSTR、SUBSTR 和 REPLACE 函数重写。

      在第一个因式子查询(WITH 子句中的子查询)中,我创建了更多输入,以测试解决方案在不同情况下是否返回正确的结果。

      with
        inputs ( str ) as (
          select 'cold, gold, "Block 12C, Jones Ave., London", car' from dual union all
          select '"One, two, three","Four, five six,",'             from dual union all
          select 'No, double-quotes, in this, string'               from dual union all
          select 'No commas in "double quotes" here'                from dual
        ),
        r ( str, init, quoted, fin ) as (
          select  str, null, null, str
            from  inputs
          union all
          select  str, 
                  init || replace(quoted, ',') || regexp_substr(fin, '[^"]*'),
                  regexp_substr(fin, '"[^"]*"'),
                  regexp_substr(fin, '([^"]*"){2}(.*)', 1, 1, null, 2)
            from  r
            where quoted is not null or fin is not null
        )
      select str, init as new_str
      from   r 
      where  quoted is null and fin is null
      ;
      
      STR                                           NEW_STR
      --------------------------------------------- -------------------------------------------
      No, double-quotes, in this, string            No, double-quotes, in this, string
      cold, gold, "Block 12C, Jay Ave, London", car cold, gold, "Block 12C Jay Ave London", car
      No commas in "double quotes" here             No commas in "double quotes" here
      "One, two, three","Four, five six,",          "One two three","Four five six",
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多