我有一个很长的字符串。
message := 'I loooove my pet animal';
这个字符串长23个字符。如果message
大于15个字符,我需要找到message
的长度,我可以将字符串分成2个字符串。例如,在这种情况下,
message1 := 'I loove my'
message2 := 'pet animal'
基本上它应该找到前一个到15个字符的整个单词的位置,并在那时将原始字符串分成2个。
请告诉我如何做到这一点。
谢谢。
答案 0 :(得分:1)
这是一个通用的解决方案 - 可能有多个输入字符串,并且输入任意长度。唯一的假设是,没有一个单词可能超过15个字符,并且两个空格之间的所有内容都被视为单词。如果“单词”可以超过15个字符,则可以调整解决方案,但需求本身需要说明在这种情况下所需的结果是什么。
我在CTE(顶部)组成两个输入字符串 - 这不是解决方案的一部分,它只是用于测试和说明。我也用简单的SQL编写了这个 - 这类问题不需要PL / SQL代码。设置处理(而不是一次一行)应该可以更好地执行。
方法是识别所有空格的位置(我也为每个字符串追加并添加空格,因此我不必处理第一个和最后一个子字符串的异常);然后我在一个递归子查询中决定每个“最大”子串应该从哪里开始,它应该在哪里结束;然后输出子串是微不足道的。我使用了一个递归查询,它应该在Oracle 11.1中运行(或者使用我使用的语法的11.2,在CTE声明中使用列名 - 它可以很容易地在11.1中更改)。在Oracle 12中,使用MATCH_RECOGINZE重写相同的想法会更容易。
with
inputs ( id, str ) as (
select 101, 'I loooove my pet animal' from dual union all
select 102, '1992 was a great year for - make something up here as needed' from dual
),
positions ( id, pos ) as (
select id, instr(' ' || str || ' ', ' ', 1, level)
from inputs
connect by level <= length(str) - length(replace(str, ' ')) + 2
and prior id = id
and prior sys_guid() is not null
),
r ( id, str, line_number, pos_from, pos_to ) as (
select id, ' ' || str || ' ', 0, null, 1
from inputs
union all
select r.id, r.str, r.line_number + 1, r.pos_to,
( select max(pos)
from positions
where id = r.id and pos - r.pos_to between 1 and 16
)
from r
where pos_to is not null
)
select id, line_number, substr(str, pos_from + 1, pos_to - pos_from - 1) as line_text
from r
where line_number > 0 and pos_to is not null
order by id, line_number
;
<强>输出强>:
ID LINE_NUMBER LINE_TEXT
---- ----------- ---------------
101 1 I loooove my
101 2 pet animal
102 1 1992 was a
102 2 great year for
102 3 - make
102 4 something up
102 5 here as needed
7 rows selected.
答案 1 :(得分:0)
首先是reverse字符串。
SELECT REVERSE(strField) FROM DUAL;
然后计算长度i = length(strField)
。
然后找到中间的第一个空格
j := INSTR( REVERSE(strField), ' ', i / 2, i)`
最后由i - j (maybe +/- 1 need to test it)
<强> DEMO 强>
WITH parameter (id, strField) as (
select 101, 'I loooove my pet animal' from dual union all
select 102, '1992 was a great year for - make something up here as needed' from dual union all
select 103, 'You are Supercalifragilisticexpialidocious' from dual
), prepare (id, rev, len, middle) as (
SELECT id, reverse(strField), length(strField), length(strField) / 2
FROM parameter
)
SELECT p.*, l.*,
SUBSTR(strField, 1, len - INSTR(rev, ' ', middle)) as first,
SUBSTR(strField, len - INSTR(rev, ' ', middle) + 2, len) as second
FROM parameter p
JOIN prepare l
ON p.id = l.id
<强>输出强>