有没有一种简单的方法可以在 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 中有一些字符串函数,例如 UPPER
、LOWER
、INITCAP
。但我只需要句子(或短语)的第一个字母大写,所有其他字母小写,考虑到单词由空格或非字母数字字符分隔,句子由标点符号分隔。
所以,转换一下:
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 行标记?