0

我正在尝试查找单词中是否存在字符串并将其提取。我使用了该instr()函数,但它作为 LIKE 函数工作:如果部分或整个单词存在,它会返回它。

在这里,我想取出字符串“服务”,它可以工作,但是如果我将“服务”更改为“服务”,它仍然可以工作。我不想要那个。如果输入“服务”,它应该返回 null 而不是“服务”

修改的:

我在这里要做的是缩写公司名称的某些部分。

这是我的数据库表的样子:

Word     | Abb
---------+-----  
Company  | com
Limited  | ltd
Service  | serv
Services | servs

这是代码:

Declare 

    Cursor Words Is

    SELECT word,abb
    FROM abbWords


    processingWord VARCHAR2(50);
    abbreviatedName VARCHAR(120);
    fullName = 'A.D Company Services Limited';

BEGIN

    FOR eachWord IN Words LOOP


      --find the position of the word in name
       wordPosition := INSTR(fullName, eachWord.word);

       --extracts the word form the full name that matches the database
       processingWord := Substr(fullName,instr(fullName,eachWord.word), length(eachWord.word));

      --only process words that exist in name
      if wordPosition > 0 then
           abbreviatedName = replace(fullName, eachWord.word,eachWord.abb);
       end if;

    END lOOP;

END;

因此,如果用户输入“服务”,我不希望返回“服务”。我的意思是,如果找不到“服务”这个词,而不是返回“服务”这个词的位置,那么词的位置应该是 0

4

4 回答 4

4

一种方法:

DECODE(INSTR('A.D Company Seervices Limited','Services'),
              0,
              NULL,
              SUBSTR('A.D Company Services Limited',
                  INSTR('A.D Company Services Limited','Services'),
                  length('Services')))

INSTR()如果未找到文本,将返回 0。DECODE()将评估第一个参数,与第二个参数进行比较,如果匹配,则返回第三个参数,如果不匹配,则返回第四个参数。(sqlfiddle链接

可以说不是最优雅的方式,但符合您的要求。

于 2012-09-04T15:03:56.783 回答
3

我认为你过于复杂了。你可以用正则表达式做任何事情。例如; 给出下表:

create table names ( name varchar2(100));
insert into names values ('A.D Company Services Limited');
insert into names values ('A.D Company Service Limited');

此查询将只返回名称'A.D Company Services Limited'

select *
  from names
 where regexp_like( name
                  , '(^|[[:space:]])services($|[[:space:]])'
                  , 'i' )

这意味着匹配字符串的开头^,或者一个空格,然后是服务,然后是字符串的结尾$,或者一个空格。这就是正则表达式与使用instr等的区别。您可以轻松地根据其他因素进行匹配。

但是,尽管这似乎是您的问题,但我认为这不是您想要做的。您正在尝试替换'serv'更宽字符串中的字符串而不替换'services'or 'service'。为此,您需要使用regexp_replace().

如果我将以下行添加到表中:

insert into names values ('A.D Company Serv Limited');

并运行此查询:

select regexp_replace( name
                     , '(^|[[:space:]])serv($|[[:space:]])'
                     , ' Services '
                     , 1, 0, 'i' )
  from names

唯一会改变的是,' Serv '在这个最新的行中,它将被替换为' Services '. 注意空格;因为您不想'Services''ServServices'这些替换,所以非常重要。

这是一个小 SQL Fiddle来演示。

于 2012-09-04T18:21:37.537 回答
2

INSTR返回一个数字:匹配字符串第一次出现的索引。您应该regexp_substr改用(10g+):

SQL> select regexp_substr('A.D Company Services Limited', 'Services') match,
  2         regexp_substr('A.D Company Service Limited', 'Services') unmatch
  3  from dual;

MATCH    UNMATCH
-------- -------
Services
于 2012-09-04T15:01:32.607 回答
2

另一种选择是使用类似的东西:

select replace(name,' serv ', ' Services ')
from names;

这将仅替换位于 2 个空格之间的单词“Serv”。

谢谢你,亚历克斯。

于 2012-09-13T14:26:37.137 回答