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

Posted

技术标签:

【中文标题】有没有一种简单的方法可以在 Oracle 8 上转换句子案例中的字符串?还是我应该使用正则表达式?【英文标题】:Is there a easy way to convert strings in a Sentence Case on Oracle 8? Or should I use regex? 【发布时间】:2015-12-29 21:52:24 【问题描述】:

我知道在 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.

【问题讨论】:

【参考方案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 但无法编译代码以使用正则表达式。

【讨论】:

【参考方案2】:

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

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 的答案可以帮助提供一个表格,其中包含文本正文中每个句子的行,可以在其上运行此表达式。

【讨论】:

以上是关于有没有一种简单的方法可以在 Oracle 8 上转换句子案例中的字符串?还是我应该使用正则表达式?的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种简单的方法来抑制 Oracle 中集合的 XML 行标记?

P3520 [POI2011]SMI-Garbage

有没有一种简单的方法可以让 unicode 在 python 中工作?

数据库迁移之从oracle 到 MySQL最简单的方法

数据库迁移之从oracle 到 MySQL最简单的方法

报告表中的 Oracle 顶点交替颜色