【问题标题】:Trim Whitespaces (New Line and Tab space) in a String in Oracle在 Oracle 中的字符串中修剪空格(换行符和制表符空间)
【发布时间】:2011-01-17 03:39:54
【问题描述】:

我需要在 Oracle 查询中修剪新行(Chr(13) 和 Chr(10) 以及字符串开头和结尾的制表符空间)。我了解到在 Oracle 中没有简单的方法可以修剪多个字符。 “修剪”功能仅修剪单个字符。如果我使用函数在循环中递归调用修剪函数,那将是性能下降。我听说 regexp_replace 可以匹配空格并删除它们。 您能否指导一种可靠的方法来使用 regexp_replace 在字符串的开头和结尾修剪多个制表符或新行或它们的组合。如果有其他方法,请指导我。

【问题讨论】:

  • “修剪”功能不只是删除单个字符。它会删除所有空格。
  • 嗨,Seshan。以下任何答案有用吗?
  • 我要检查一下。会检查并让你知道..

标签: sql oracle trim


【解决方案1】:

如果您有 Oracle 10g,REGEXP_REPLACE 非常灵活。

使用以下字符串作为测试:

chr(9) || 'Q   qwer' || chr(9) || chr(10) ||
chr(13) || 'qwerqwer     qwerty' || chr(9) || 
chr(10) || chr(13)

[[:space:]] 将删除所有空格,([[:cntrl:]])|(^\t) 正则表达式将删除非打印字符和制表符。

select
    tester,
    regexp_replace(tester, '(^[[:space:]]+)|([[:space:]]+$)',null)
            regexp_tester_1,
    regexp_replace(tester, '(^[[:cntrl:]^\t]+)|([[:cntrl:]^\t]+$)',null) 
            regexp_tester_2
from
    (
    select
        chr(9) || 'Q   qwer' || chr(9) || chr(10) ||
                chr(13) || 'qwerqwer     qwerty' || chr(9) || 
                chr(10) || chr(13) tester 
    from 
        dual
    )

返回:

  • REGEXP_TESTER_1:“Qqwerqwerqwerqwerty
  • REGEXP_TESTER_2:“Q qwerqwerqwer qwerty

希望这有一些用处。

【讨论】:

  • 赞成 REGEXP_REPLACE 建议和精美布局的示例(对于那些使用 SO 的人应该有特别的奖励)。但它并没有按照 OP 的要求执行,它只是在多行字符串的 startend 处删除。我将冒昧编辑以相应地调整正则表达式。
  • 顺便说一句,测试时,如果将regexp_replace 上的第三个参数设置为'.' 而不是null,则更容易看到发生了什么
  • 嗨@Andrew - 感谢您的支持。但是,我将不得不回滚您的更改,因为您的新版本现在意味着该示例不会产生规定的输出。该示例的重点是演示由[[:space:]][[:ctrl:]] 参数处理的空白宽度。也许您想在我的简化示例之后更新答案以在答案末尾包含您修改后的表达式。另外,不同意使用'.'。而不是 null - null 清楚地表明你什么都没有替换。
  • 这是我测试中最后一个字母字符的剪切
【解决方案2】:

我将如何实现它:

     REGEXP_REPLACE(text,'(^[[:space:]]*|[[:space:]]*$)')

【讨论】:

  • 不知道为什么这没有得到更多的关注!这是页面上唯一正确的答案。也很简洁。
  • 这是最好的答案
  • 正确但影响性能。我想知道为什么 Oracle 不允许在没有正则表达式的情况下使用这么小的函数。
  • 警告:Oracle 的 [:space:] 字符类似乎与不间断空格不匹配。
【解决方案3】:

又快又脏的翻译功能怎么样?

这将删除 string1 中每个字符的所有出现:

SELECT translate(
           translate(
               translate(string1, CHR(10), '')
           , CHR(13), '')
       , CHR(09), '') as massaged
FROM BLAH;

Regexp_replace 是一个选项,但根据表达式的复杂程度,您可能会看到性能下降。

【讨论】:

  • 这在两个层面上是错误的。首先,每当您将 null(例如 '')作为第三个参数传递给 TRANSLATE 时,它将始终返回 null。其次,TRANSLATE 作用于整个字符串,而不仅仅是字符串的开头和结尾(按照 OP 的要求)。参考:docs.oracle.com/cd/E11882_01/server.112/e10592/…
  • Jeffrey 说这是非常正确的,除非您将 '' 替换为 ' '(空格)。此外, translate 允许一次指定多个要替换的字符。这做同样的事情: select trim(translate(' example ', chr(10) || chr(13) || chr(09), ' ')) as example from dual;请记住,它仍然会替换字符串中的这些字符。
  • 嗯,stackoverflow cmets 用一个替换连续的空格。上面的 SQL 语句中的 '' 之间应该有三个空格。
  • 谢谢。这很有用,但最好使用 REPLACE 而不是 TRANSLATE。
【解决方案4】:

您可以同时使用 LTRIM 和 RTRIM。

select rtrim(ltrim('abcdab','ab'),'ab') from dual;

如果您只想在带有 CHR(10) 的情况下修剪 CHR(13),它会变得更加复杂。首先,将组合字符串转换为单个字符。然后 LTRIM/RTRIM 那个字符,然后将单个字符替换回组合字符串。

select replace(rtrim(ltrim(replace('abccccabcccaab','ab','#'),'#'),'#'),'#','ab') from dual;

【讨论】:

    【解决方案5】:
    TRANSLATE (column_name, 'd'||CHR(10)||CHR(13), 'd')
    

    'd' 是一个虚拟字符,因为如果第三个参数为空,则翻译不起作用。

    【讨论】:

      【解决方案6】:

      适用于什么版本的 Oracle? 10g+ 支持正则表达式 - 请参阅 this thread on the OTN Discussion forum for how to use REGEXP_REPLACE 将不可打印的字符更改为 ''

      【讨论】:

      • 找不到页面......这就是为什么“仅链接答案”不好
      【解决方案7】:

      我知道这不是这个问题的严格答案,但我一直在几个需要按照以下规则转换文本数据的场景中工作:

      1. 字符串开头没有空格ctrl字符
      2. 字符串末尾没有空格ctrl字符
      3. 空格ctrl chars的多个出现将被替换为单个空格

      下面的代码遵循上面详述的规则:

      WITH test_view AS (
        SELECT CHR(9) || 'Q   qwer' || CHR(9) || CHR(10) ||
               CHR(13) || ' qwerqwer     qwerty  ' || CHR(9) || 
               CHR(10) || CHR(13) str
        FROM DUAL
      ) SELECT 
           str original
          ,TRIM(REGEXP_REPLACE(str, '([[:space:]]{2,}|[[:cntrl:]])', ' ')) fixed
        FROM test_view;
      
      
      ORIGINAL               FIXED                 
      ---------------------- ----------------------
          Q   qwer           Q qwer qwerqwer qwerty
      
       qwerqwer     qwerty                                         
      
      1 row selected.
      

      【讨论】:

        【解决方案8】:

        如果有人希望转换位于 2 或 3 个不同行中的 1 个变量中的数据,如下所示

        'Data1
        
        Data2'
        

        并且您想将数据显示为“Data1 Data2”,然后在下面使用

        select TRANSLATE ('Data1
        
        Data2', ''||CHR(10), ' ') from dual;
        

        我花了几个小时才得到正确的输出。多亏了我,我才为您节省了 1 或 2 小时 :)

        【讨论】:

          【解决方案9】:

          如果 Oracle 解决方案看起来过于复杂,我会使用静态方法创建一个 java 类,然后将其作为一个包安装在 Oracle 中。这可能没有那么高效,但您最终会发现其他情况(例如将日期转换为毫秒),您会发现 java 回退很有帮助。

          【讨论】:

            【解决方案10】:

            以下代码可用于删除文本列中的新行和表空间

            Select replace(replace(TEXT,char(10),''),char(13),'')
            

            【讨论】:

            • 不起作用。问题中最初发布的字符串中间可能有chr(13)chr(10)
            【解决方案11】:

            试试下面的代码。 如果您在单列中输入多行,它将起作用。

            create table  products (prod_id number , prod_desc varchar2(50));
            
            insert into products values(1,'test first
            
            test second
            
            test third');
            
            select replace(replace(prod_desc,chr(10),' '),chr(13),' ') from products  where prod_id=2; 
            

            输出:测试第一测试第二测试第三

            【讨论】:

              【解决方案12】:
              TRIM(BOTH chr(13)||chr(10)||' ' FROM str)
              

              【讨论】:

              • 很高兴提供一些代码,但它应该附带一些解释以指出更改以及为什么它是 OP 问题的解决方案。
              • 虽然这段代码 sn-p 可以解决问题,including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
              • ORA-30001:修剪集应该只有一个字符
              【解决方案13】:

              不要多次使用regexp_replace,而是使用(\s),如下所示;

              SELECT regexp_replace('TEXT','(\s)','')
              FROM dual;
              

              【讨论】:

                【解决方案14】:

                以下代码从字符串两侧删除换行符:

                select ltrim(rtrim('asbda'||CHR(10)||CHR(13) ,''||CHR(10)||CHR(13)),''||CHR(10)||CHR(13))  from dual
                

                但在大多数情况下,这个就够了:

                select rtrim('asbda'||CHR(10)||CHR(13) ,''||CHR(10)||CHR(13)))  from dual
                

                【讨论】:

                  【解决方案15】:
                  UPDATE My_Table
                     SET Mycolumn1 =
                             TRIM (
                                 TRANSLATE (Mycolumn1,
                                            CHR (10) || CHR (11) || CHR (13),
                                            '    '))
                   WHERE (   INSTR (Mucolumn1, CHR (13)) > 0
                          OR INSTR (Mucolumn1, CHR (10)) > 0
                          OR INSTR (Mucolumn1, CHR (11)) > 0);
                  

                  【讨论】:

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