使用instr查找完全匹配的Pl / Sql

时间:2012-09-04 14:47:23

标签: string oracle plsql extract substr

我试图找出一个字符串中是否存在字符串并将其解压缩。我使用了instr()函数,但这可以作为LIKE函数:如果存在部分或整个单词,则返回它。

在这里,我希望得到字符串'Services',但是如果我将'Services'更改为'Service',它仍然有效。我不希望这样。如果输入“服务”,则应返回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 个答案:

答案 0 :(得分: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 link

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

答案 1 :(得分:3)

我认为你过于复杂了。您可以使用regular expressions执行所有操作。例如;如下表所示:

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''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',所以这些非常重要。

这是一个little SQL Fiddle来演示。

答案 2 :(得分: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

答案 3 :(得分:2)

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

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

这将只取代位于2个空格之间的“Serv”字样。

谢谢你, 亚历克斯。