【问题标题】:initcap only for words with more than three characterinitcap 仅适用于超过三个字符的单词
【发布时间】:2019-09-16 18:06:27
【问题描述】:

我正在尝试创建一个将 initcap 应用于字段的选择语句,但我想只将超过三个字符的单词设为大写。

请注意,我无法创建外部函数,并且我的问题没有通过这个答案解决: Initcap skip words smaller than 4 characters

因为他们解决了使用手动检查匹配项的过程。

所以我想使用一些东西:

SELECT REGEXP_REPLACE(initcap(myField),"\w{1,10}\b") FROM dual

MyField 包含类似 GUNS N ROSES 的内容,我想转变成 Guns n Roses

【问题讨论】:

  • REGEXP_REPLACE() 需要 3 个参数:列名、正则表达式和替换字符串。

标签: sql regex oracle


【解决方案1】:

你需要为它执行单独的逻辑。

如果length超过3个字符,则需要将语句分解为单个单词并执行initcap。之后使用aggregate function 将它们组合起来。

WITH DATAA AS
(SELECT 'GUNS N ROSES' AS STR FROM DUAL)

SELECT LISTAGG(CASE WHEN LENGTH(STRR) > 3       
                    THEN INITCAP(STRR) 
                    ELSE STRR 
               END, ' ')
       WITHIN GROUP (ORDER BY LVL) AS RESULT
FROM
  (SELECT LEVEL AS LVL, 
          LOWER(REGEXP_SUBSTR(STR, '[^ ]+', 1, LEVEL)) AS STRR
     FROM DATAA
   CONNECT BY LEVEL <= REGEXP_COUNT(STR, ' ') + 1);

db<>fiddle demo

干杯!!

【讨论】:

  • 干得好,但您在示例末尾缺少一个紧跟括号。
【解决方案2】:

与 Tejash 的回答类似,但有一些额外的逻辑可以在多行上执行 CONNECT BY。

-- example data
with mytable as (select 'GUNS N ROSES' as myfield from dual
            union select 'SALPHEN AAN DEN RIJN' from dual
            union select 'KAAG EN BRAASSEM' from dual)
-- query
select listagg(CASE WHEN length(words.word) > 3 
                    THEN initcap(words.word) 
                    ELSE lower(words.word) 
               END, ' ') within group (order by words.lvl)
from 
  (select myfield, regexp_substr(myfield,'\w+', 1, level) as word, level as lvl
    from mytable
    connect by regexp_substr(myfield, '\w+', 1, level) is not null
      and PRIOR myfield = myfield
      and PRIOR SYS_GUID() is not null) words
group by words.myfield  
;

【讨论】:

    【解决方案3】:

    逐字替换值,无需拆分和重新聚合句子。

    Oracle 设置

    CREATE TABLE table_name( sentence ) AS
    SELECT 'GUNS N ROSES' FROM DUAL UNION ALL
    SELECT 'THIS IS A SENTENCE THAT SHOULD BE IN INITCAPS IF IT HAS MORE THAN THREE LETTERS' FROM DUAL UNION ALL
    SELECT 'FOUR THREE TWO ONE' FROM DUAL
    

    查询

    WITH replaced ( sentence, startidx, endidx ) AS (
      SELECT LOWER( sentence ),
             1,
             REGEXP_INSTR( sentence, '\W', 1 )
      FROM   table_name
    UNION ALL
      SELECT CASE
             WHEN endidx - startidx <= 3
             THEN sentence
             ELSE  SUBSTR( sentence, 1, startidx - 1 )
                || INITCAP( SUBSTR( sentence, startidx, endidx - startidx ) )
                || SUBSTR( sentence, endidx )
             END,
             endidx + 1,
             REGEXP_INSTR( sentence, '\W', endidx + 1 )
      FROM   replaced
      WHERE  endidx > 0
    )
    SELECT CASE
           WHEN LENGTH( sentence ) - startidx <= 3
           THEN sentence
           ELSE  SUBSTR( sentence, 1, startidx - 1 )
              || INITCAP( SUBSTR( sentence, startidx ) )
           END AS sentence
    FROM   replaced
    WHERE  endidx = 0
    

    输出

    |句子 | | :------------------------------------------------ ------------------------------ | |枪与玫瑰 | |四三二一| |如果它有三个以上的字母,这是一个应该在 Initcaps 中的句子 |

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-04
      • 2014-09-25
      • 1970-01-01
      • 2016-05-26
      • 2017-07-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多