Sql 在Oracle中使用Regex\u substr选择字符串,直到最后一次出现长度在\n个字符以内的空格
我们有一个问题,Oracle数据库中的列的字符长度比另一个系统中的字段长 因此,我尝试使用case语句和substr来拆分长度超过40个字符的字符串。到目前为止,我的case语句执行了我希望它们执行的操作,即它将字符串的前40个字符保留在列_a中,然后将字符串的其余部分放置在列_b中 然而,我遇到的问题是,通过使用substr,字符串在单词中间被分割 所以我想知道是否有人知道一些正则表达式,我可以与regex_substr一起使用,它们将-Sql 在Oracle中使用Regex\u substr选择字符串,直到最后一次出现长度在\n个字符以内的空格,sql,regex,oracle,substr,Sql,Regex,Oracle,Substr,我们有一个问题,Oracle数据库中的列的字符长度比另一个系统中的字段长 因此,我尝试使用case语句和substr来拆分长度超过40个字符的字符串。到目前为止,我的case语句执行了我希望它们执行的操作,即它将字符串的前40个字符保留在列_a中,然后将字符串的其余部分放置在列_b中 然而,我遇到的问题是,通过使用substr,字符串在单词中间被分割 所以我想知道是否有人知道一些正则表达式,我可以与regex_substr一起使用,它们将- 选择一个字符串,最多不超过40个字符的最后一个空格-用
CASE WHEN Length(column_a) > 10 THEN SubStr(column_a, 0, 40) END AS column_a,
CASE WHEN Length(column_a) > 40 THEN SubStr(addressnum, 41) END AS column_b
我对正则表达式一点也不熟悉,因此非常感谢您的帮助 我已经用instr/substr解决了:
select substr(column_a,1,instr(substr(column_a,1,40), ' ', -1 )) column1,
substr(column_a,instr(substr(column_a,1,40), ' ', -1 )+1, 40) column2
from table1
今天OTN上发布了一个非常类似的问题 我发布了一个通用解决方案,它也将涵盖这里提出的问题。如果将来有类似的需求,它可能会派上用场 对于在SO上发布的问题,
row\u length
表将只有一行,r\u id=1
和r\u len=40
。为了演示,我在下面展示了一个与我在OTN上使用的不同的输入字符串
设置:
create table input_strings (str_id number, txt varchar2(500));
insert into input_strings values (1,
'One Hundred Sixty-Nine Thousand Eight Hundred Seventy-Four Dollars And Nine Cents');
insert into input_strings values (2, null);
insert into input_strings values (3, 'Mathguy rules');
create table row_lengths (r_id number, r_len number);
insert into row_lengths values (1, 40);
commit;
select * from input_strings;
STR_ID TXT
------- ---------------------------------------------------------------------------------
1 One Hundred Sixty-Nine Thousand Eight Hundred Seventy-Four Dollars And Nine Cents
2
3 Mathguy rules
3 rows selected
select * from row_lengths;
R_ID R_LEN
------- ----------
1 40
1 row selected.
查询和输出:(注意:我包括令牌长度以验证第一个令牌不超过40个字符。OP没有回答第二个令牌是否可以超过40个字符;如果不能,可以向行长度
表中添加行,可能每行的r\u len=40
)
太好了,不知道怎么做,但效果很好!非常感谢您的支持help@NickMoth伟大的问题是,第三个参数为-1的Instr变为backward,它是否保证在位置40之前的最后一个空间进行拆分在所有情况下都有效?这个问题有两个部分:第一,所有输入字符串是否都少于80个字符?第二,如果位置40之前的最后一个空格位于位置35,而剩余的字符串是42个字符,该怎么办?和-您想对空格做什么-将其包含在第一个字符串中?用第二根弦?或者不将其包含在任一字符串中?
with
r ( r_id, r_len ) as (
select r_id , r_len from row_lengths union all
select max(r_id) + 1, 4000 from row_lengths union all
select max(r_id) + 2, null from row_lengths
),
b (str_id, str, r_id, token, prev_pos, new_pos) as (
select str_id, txt || ' ', -1, null, null, 0
from input_strings
union all
select b.str_id, b.str, b.r_id + 1,
substr(str, prev_pos + 1, new_pos - prev_pos - 1),
b.new_pos,
new_pos + instr(substr(b.str, b.new_pos + 1, r.r_len + 1) , ' ', -1)
from b join r
on b.r_id + 2 = r.r_id
)
select str_id, r_id, token, nvl(length(token), 0) as len
from b
where r_id > 0
order by str_id, r_id;
STR_ID R_ID TOKEN LEN
------- ------- ------------------------------------------------ -------
1 1 One Hundred Sixty-Nine Thousand Eight 37
1 2 Hundred Seventy-Four Dollars And Nine Cents 43
2 1 0
2 2 0
3 1 Mathguy rules 13
3 2 0
6 rows selected.