【问题标题】:How to split a string without truncating words in PL/SQL?如何在不截断 PL/SQL 中的单词的情况下拆分字符串?
【发布时间】:2019-10-04 17:15:05
【问题描述】:

我有一个表Data,其中一个字段Note 包含一个长字符串。我想每 30 个字符拆分每个字符串的内容,而不截断单词。这意味着如果拆分要截断一个单词,它应该在该单词之前拆分并从下一个重新开始拆分过程:

使用拆分每个 7 个字符的示例

数据

--------------------------
| Id | Note              |
--------------------------
|  1 |I am dumb using SQL|
--------------------------
... more rows ...
--------------------------

结果

----------------
| Id | Note    |    
----------------
|  1 |I am     |
----------------
|  2 |dumb     |
----------------
|  3 |using    |
----------------
|  4 |SQL      |
----------------

注意第一次拆分是如何发生的:前 7 个字符是 I am du,因为第七个字符的拆分会截断单词 dumb,拆分在之前应用,结果是 I am

复制示例的一些代码以及我解决问题的尝试:

CREATE TABLE Data (ID, NOTA);
INSERT INTO Data (ID, NOTA)
VALUES (10, 'NEL MEZZO DEL CAMMIN DI NOSTRA VITA MI RITROVAI IN UNA SELVA OSCURA');

SELECT 
ID, rownum AS rn
                ,trim(regexp_substr(NOTA,'.{1,60}( |$)',1,rownum)) AS SPLIT_NOTA
FROM Data  connect by rownum <= ceil(length(NOTA)/60)

【问题讨论】:

  • 你尝试了吗?我们不解决家庭作业。
  • 我当然试过了……不,这不是家庭作业!我将发布一些代码来复制示例和我的尝试
  • 如果单词长于 7 个字符怎么办?
  • 实际值长度拆分为 60 或 30,因此这是一个罕见的例外

标签: sql regex plsql


【解决方案1】:

假设你不想剪长词:

([^ ]{1}.{1,6}(?= ))|([^\n ]{1,})

正则表达式主要组的解释:

([^ ]{1}.{1,6}(?= )) - 一个非空格后跟最多 6 个字符,它们后面有一个空格(正向前瞻)。

([^\n ]{1,}) - 一个或多个非空格,非换行符。这部分正则表达式负责覆盖比 7(或 30)个字符更长的单词并覆盖字符串中的最后一个单词。

您应该将6 替换为n-1,其中n 是可以不截断的字符数(在您的情况下为7 或30)。我使用 Notepad++ 开发了这个正则表达式,我不能保证它会在你的环境中工作。

【讨论】:

  • Oracle 的正则表达式不支持前瞻/后瞻断言。
【解决方案2】:

我假设您正在尝试获取一个处理多行的示例?

with tbl_source(id, txt) as (
  select 1, 'I am dumb using SQL'     from dual union all
  select 2, 'This is a test of row 2' from dual
),
tbl_main(id, rownbr, txt, txt_length) as (
select id, level as rownbr, trim(regexp_substr(txt,'.{1,7}( |$)',1,level)) as txt,
       length(trim(regexp_substr(txt,'.{1,7}( |$)',1,level))) txt_length
       from tbl_source
       connect by level <= ceil(length(txt)/7)+1
       and prior txt = txt
       and prior sys_guid() is not null 
)
select id, rownbr, txt, txt_length
from tbl_main
where txt is not null
order by id, rownbr;

输出:

        ID     ROWNBR TXT                     TXT_LENGTH
---------- ---------- ----------------------- ----------
         1          1 I am                             4
         1          2 dumb                             4
         1          3 using                            5
         1          4 SQL                              3
         2          1 This is                          7
         2          2 a test                           6
         2          3 of row                           6
         2          4 2                                1

8 rows selected.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 2020-03-07
    • 2020-04-09
    相关资源
    最近更新 更多