统计英文字符串中单词的个数SQL

jansonleader 2010-11-02 10:38:17
某个表中有一个字段是英文的字符串,单词之间用空格隔开,需要统计其中单词的个数。难点有:
1,字符串中可能有数字,例如"I am 5 years old",数字算一个单词。因此例子中单词数为5;
2 , 分割单词的空格可能有一到多个,例如"This is fun"。例子中单词数为3;
Oracle中好像没有类似的函数。请教各位热心人,帮忙提供思路或参考语句。
Thanks in advance!
...全文
1219 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
singzero 2012-02-16
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 gelyon 的回复:]

引用 9 楼 yy_mm_dd 的回复:

把空格字符用空字符代替,然后把两个长度减掉
SQL code

select length('I am 5 years old')-length(regexp_replace('I am 5 years old',' ',''))+1 from dual


显然多个空格时候不行啊。。
[/Quote]

为什么多个空格就不可用????
singzero 2012-02-16
  • 打赏
  • 举报
回复
select length(REGEXP_REPLACE('I am 5 years old','[ ]*[[:alnum:]]+[ ]*','@')) from dual
这个很经典
jansonleader 2010-11-03
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 wkc168 的回复:]

引用 24 楼 jansonleader 的回复:
引用 13 楼 gelyon 的回复:

SQL code

--补充:
--此函数可以过滤其他标点符号(如逗号,分号。。),只要标点符号紧跟在单词后面就OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBE……
[/Quote]

感谢你的解决方法,确实能够满足我的要求。不过已经结贴了,没法给你分了。非常感谢!
onemetre 2010-11-02
  • 打赏
  • 举报
回复
select length(REGEXP_REPLACE('I am 5 years old','[ ]*[[:alnum:]]+[ ]*','@')) from  dual
jansonleader 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 yy_mm_dd 的回复:]

把空格字符用空字符代替,然后把两个长度减掉
SQL code

select length('I am 5 years old')-length(regexp_replace('I am 5 years old',' ',''))+1 from dual
[/Quote]

谢谢,这个也是我最初想到的思路,我写的是这个样子的:
CREATE OR REPLACE FUNCTION get_char_count(src IN VARCHAR2, sep in varchar2)
RETURN number
IS
pcount number;
BEGIN
pcount := ((length(src) - length(replace(src, sep)))/length(sep) + 1);
return pcount;
END;
但是正如楼下所说的,对于多个空格的情况就不适用了!
gelyon 2010-11-02
  • 打赏
  • 举报
回复

--补充:
--此函数可以过滤其他标点符号(如逗号,分号。。),只要标点符号紧跟在单词后面就OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LOOP
IF SubStr(word,i,1) = Chr(32) AND SubStr(word,i-1,1)!=Chr(32) THEN
num:=num+1;
END IF ;
END LOOP;
RETURN num+1;
END;

--测试:
SELECT get_words('My name is paddy, I am 23 years old; I like CSDN.') words FROM dual;

--结果:
WORDS
--------
12
jansonleader 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xiaobn_cn 的回复:]

我写了个函数,由于oracle限制,只支持40000字节以内的字符串
SQL code

create or replace function f_getcount(a varchar2) return number is
cnt number;
i number;
str varchar2(4000);
flag number; -- 上一个字符是否空格 1 是 0 不是
begin
……
[/Quote]

谢谢你提供的思路!这是个好的着手点。
jansonleader 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 gelyon 的回复:]

引用 6 楼 xiaobn_cn 的回复:

5楼还是少了点,句尾空格你没有考虑到呢。


楼主好像没说也,呵呵。。。
[/Quote]

呵呵~ 是没有句尾空格的。谢谢
gelyon 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 yy_mm_dd 的回复:]

把空格字符用空字符代替,然后把两个长度减掉
SQL code

select length('I am 5 years old')-length(regexp_replace('I am 5 years old',' ',''))+1 from dual
[/Quote]

显然多个空格时候不行啊。。
YY_MM_DD 2010-11-02
  • 打赏
  • 举报
回复
把空格字符用空字符代替,然后把两个长度减掉

select length('I am 5 years old')-length(regexp_replace('I am 5 years old',' ',''))+1 from dual
minitoy 2010-11-02
  • 打赏
  • 举报
回复
感觉正则表达式应该能做到,等表达式高手.
gelyon 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 xiaobn_cn 的回复:]

5楼还是少了点,句尾空格你没有考虑到呢。
[/Quote]

楼主好像没说也,呵呵。。。
xiaobn_cn 2010-11-02
  • 打赏
  • 举报
回复
5楼还是少了点,句尾空格你没有考虑到呢。
gelyon 2010-11-02
  • 打赏
  • 举报
回复

--忘记了你说不止一个空格,这个是最终版!OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LOOP
IF SubStr(word,i,1) = Chr(32) AND SubStr(word,i-1,1)!=Chr(32) THEN
num:=num+1;
END IF ;
END LOOP;
RETURN num+1;
END;

SELECT get_words('I am 5 years old') FROM dual;
gelyon 2010-11-02
  • 打赏
  • 举报
回复

CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LOOP
IF SubStr(word,i,1) = Chr(32) THEN
num:=num+1;
END IF ;
END LOOP;
RETURN num+1;
END;

SELECT get_words('I am 5 years old') FROM dual;
xiaobn_cn 2010-11-02
  • 打赏
  • 举报
回复
多打了个0,只支持4000以内
xiaobn_cn 2010-11-02
  • 打赏
  • 举报
回复
我写了个函数,由于oracle限制,只支持40000字节以内的字符串

create or replace function f_getcount(a varchar2) return number is
cnt number;
i number;
str varchar2(4000);
flag number; -- 上一个字符是否空格 1 是 0 不是
begin
str := a || ' ';
cnt := 0;
flag := 1;
for i in 1..length(str) loop
-- 如果遇到空格
if substr(str,i,1) = ' ' then
-- 判断前面是否是连续的空格,不是则认为新的单词
if flag = 0 then
cnt := cnt + 1;
end if;
end if;

if substr(str,i,1) = ' ' then
flag := 1;
else
flag := 0;
end if;
end loop;

return cnt;
end ;

jansonleader 2010-11-02
  • 打赏
  • 举报
回复
静候Oracle大师!
心中的彩虹 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 jansonleader 的回复:]
引用 13 楼 gelyon 的回复:

SQL code

--补充:
--此函数可以过滤其他标点符号(如逗号,分号。。),只要标点符号紧跟在单词后面就OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Le……
[/Quote]


--试试这个

create or replace function fun_sumzf2(v_char varchar2) return number
as
num number:=0;
str varchar2(100);
j number;
begin
str:=trim(v_char);
select length(str||' ')-length(replace(str||' ',' ','')) into j from dual;
for i in 1..j loop
if instr(str,' ',1,i)!=instr(str,' ',1,i+1)-1 then
num:=num+1;
end if;
end loop;
return num;
end;

--测试的结果

SQL> select fun_sumzf2('I 2') from dual
2 /

FUN_SUMZF2('I2')
----------------
2

SQL> select fun_sumzf2('I 2 b') from dual
2 /

FUN_SUMZF2('I2B')
-----------------
3

SQL> select fun_sumzf2('I 2 b ') from dual
2 /

FUN_SUMZF2('I2B')
-----------------
3

SQL> select fun_sumzf2('2') from dual
2 /

FUN_SUMZF2('2')
---------------
1





jansonleader 2010-11-02
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 gelyon 的回复:]

SQL code

--补充:
--此函数可以过滤其他标点符号(如逗号,分号。。),只要标点符号紧跟在单词后面就OK!
CREATE OR REPLACE FUNCTION get_words(word IN VARCHAR2 )
RETURN NUMBER
IS
num NUMBER:=0;
BEGIN
FOR i IN 1..Length(word) LO……
[/Quote]

你说的可以过滤其他符号是不是要更改chr(32)变成其他字符?
加载更多回复(8)

17,088

社区成员

发帖
与我相关
我的任务
社区描述
Oracle开发相关技术讨论
社区管理员
  • 开发
  • Lucifer三思而后行
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧