Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在Oracle中使用Regex\u substr选择字符串,直到最后一次出现长度在\n个字符以内的空格_Sql_Regex_Oracle_Substr - Fatal编程技术网

Sql 在Oracle中使用Regex\u substr选择字符串,直到最后一次出现长度在\n个字符以内的空格

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个字符的最后一个空格-用

我们有一个问题,Oracle数据库中的列的字符长度比另一个系统中的字段长

因此,我尝试使用case语句和substr来拆分长度超过40个字符的字符串。到目前为止,我的case语句执行了我希望它们执行的操作,即它将字符串的前40个字符保留在列_a中,然后将字符串的其余部分放置在列_b中

然而,我遇到的问题是,通过使用substr,字符串在单词中间被分割

所以我想知道是否有人知道一些正则表达式,我可以与regex_substr一起使用,它们将-

  • 选择一个字符串,最多不超过40个字符的最后一个空格-用于 a列
  • 在40个字符内的最后一个空格后选择一个字符串-用于 b列
  • 以下是我迄今为止对substr的案例陈述:

    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.