是否有一种简单的方法可以在Oracle 8的句子中转换字符串?或者我应该使用正则表达式?

时间:2015-12-29 21:52:25

标签: regex oracle oracle8i

我知道在Oracle中有一些字符串函数,如UPPERLOWERINITCAP。但我只需要大写的句子(或短语)的第一个字母,所有其他小写的字母,考虑到单词由空格或非字母数字的字符和由标点符号分隔的句子分隔。

所以,转换一下:

PEDIDO CANCELADO, DEVIDO AO ENCERRAMENTO DE INVESTIMENTO. SERÁ GERADA UMA NOVA REQUISIÇÃO PARA REGULARIZAR ESTA QUESTÃO.

Pedido cancelado, devido ao encerramento de investimento. Será gerada uma nova requisição para regularizar esta questão.

2 个答案:

答案 0 :(得分:1)

就像在Oracle 10g中引入了本机函数并支持SQL和PL / SQL中的正则表达式一样,我在plsql中用来解决我的问题的一个选项就是创建一个函数:

create or replace function scase(s in varchar2) return varchar2 as
  s_len    number;  
  cur      char(2); /*char(2) for accented character */
  up       boolean;
  terminal char(10) := '.?!]';
  r        varchar2(32767);
begin

  s_len := length(trim(s));

  if s_len = 0 then
    return r;
  end if;

  r := r || UPPER(substr(s, 0, 1)); /*First character of sentence*/

  for i in 2 .. s_len loop

    cur := substr(s, i, 1);

    if up = TRUE then
      if cur = ' ' then 
        r := r || ' ';
      else
        r := r || Upper(trim(cur));
        up := FALSE;        
      end if;
    else
       if cur = ' ' then 
        r := r || ' ';
      else
        r := r || Lower(trim(cur));
      end if;
    end if;

    /*I have found a bug here(Oracle 8i): instr return 7 when is ' ' (blank space) */
    if instr(terminal, trim(cur)) between 1 and 6 then
      up := TRUE;      
    end if;
  end loop;

  return r;
exception
  when others then
    raise;
end;

另一种选择是在java 2中创建一个类。2000年8月的Oracle 8i(8.1.7)的最后一个版本支持java 2.

因此,您可以在java中创建代码,如:

create or replace and compile java source named tosentencecase as
public class toSentenceCase
{
 public static String toSentenceCase(String s) {
       String r = "";
       if (s.length() == 0) {
           return r;
       }
       char c1 = s.charAt(0);
       r = r + Character.toUpperCase(c1);  /*First character of sentence*/

       boolean up = false;
       char[] terminal = {'.', '?', '!'};
       for (int i = 1; i < s.length(); i++) {
           char cur = s.charAt(i);
           if (up) {
               if (cur == ' ') {
                   r = r + cur;
               } else {
                   r = r +  Character.toUpperCase(cur);;
                   up = false;
               }
           } else {
               r = r +  Character.toLowerCase(cur);;
           }
           for (int j = 0; j < terminal.length; j++) {
               if (cur == terminal[j]) {
                   up = true;
                   break;
               }
           }
       }
       return r;
   }
}

创建一个调用该代码的函数后,就像那样:

CREATE OR REPLACE FUNCTION toSentenceCase (s IN STRING) RETURN STRING
AS LANGUAGE JAVA
NAME 'toSentenceCase.toSentenceCase (java.lang.String) return String';

之后就像正常函数一样调用:

Connected to Oracle8i Enterprise Edition Release 8.1.7.3.0 

SQL> Select toSentenceCase('PEDIDO CANCELADO, DEVIDO AO ENCERRAMENTO DE INVESTIMENTO. SERÁ GERADA UMA NOVA REQUISIÇÃO PARA REGULARIZAR ESTA QUESTÃO.')
  2    from dual;

TOSENTENCECASE('PEDIDOCANCELAD
--------------------------------------------------------------------------------
Pedido cancelado, devido ao encerramento de investimento. Será gerada uma nova r

SQL> 

PS:使用java 2(嵌入在Oracle 8i中)我尝试导入java.util.regex.Matcher并导入java.util.regex.Pattern但是无法编译代码以使用正则表达式。

答案 1 :(得分:0)

在一个句子的情况下,以下内容将起作用。

with YOUR_TABLE AS 
(
  select 'THIS is a SENTENCE.' as YOUR_COLUMN from dual
)

select UPPER(SUBSTR(YOUR_COLUMN,1,1))||LOWER(SUBSTR(YOUR_COLUMN,2,LENGTH(YOUR_COLUMN))) as SENTENCE from YOUR_TABLE

SENTENCE          
-------------------
This is a sentence.

类似于Splitting string into multiple rows in Oracle的答案可能有助于提供一个表,该表包含文本正文中每个句子的行,可以在该表上运行该表达式。