我有一个表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
,该拆分之前被应用,结果为{{1 }}。
一些代码可以复制示例以及我尝试解决的问题:
I am
答案 0 :(得分:2)
假设您不想删节较长的单词:
([^ ]{1}.{1,6}(?= ))|([^\n ]{1,})
正则表达式主要组的说明:
([^ ]{1}.{1,6}(?= ))
-一个非空格,后跟最多6个字符,后跟一个空格(正向超前)。
([^\n ]{1,})
-一个或多个非空格,非换行符。正则表达式的这一部分负责覆盖比7(或30)个字符更长的单词,并覆盖字符串中的最后一个单词。
您应将6
替换为n-1
,其中n
是不被截断而可以容纳的字符数(在您的情况下为7或30)。我已经使用Notepad ++开发了此正则表达式,但不能保证它会在您的环境中正常工作。
答案 1 :(得分:1)
我假设您正在尝试获取处理多个行的示例?
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.