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

Is there a easy way to convert strings in a Sentence Case on Oracle 8? Or should I use regex?

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

因此,转换为:

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.

就像仅在 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中创建一个class 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 但无法编译代码以使用正则表达式。

如果是一个句子,下面的就可以了。

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 的答案可能有助于提供一个 table 包含文本正文中每个句子的行,这个表达式可以是 运行.