如果在plsql中找到匹配项,需要解析用冒号分隔的字符串并消除部分字符串

时间:2013-07-26 11:21:09

标签: regex oracle plsql

我知道这个话题已经多次讨论了,我查看了多个帖子和答案,但找不到我需要做的事情。

我正在尝试搜索字符串,其中varchar2的多个值由':'分隔,如果在另一个字符串上找到匹配项,则删除匹配的字符串的一部分,并使用其余的字符串更新表。字符串。

我使用str和instr函数的组合编写代码,但是使用regexp或集合寻找更优雅的解决方案。

例如,输入字符串如下所示:('abc:defg:klmnp)。需要找到例如字符串的一部分(可以在任何位置),并将其删除,结果如下所示:(abc:klmnp)

编辑 - 从评论中复制: 输入字符串(abc:defg:klmn:defgb)。让我们说我正在寻找defg,只有defg必须被删除,而不是defgb。现在,就像我之前提到的那样,下次我可能正在寻找位置1或最后位置的值。因此,要删除的字符串的所需部分可能并不总是从两侧包含在“:”中,而是取决于它在字符串中的位置,从右侧,左侧或从两侧。

2 个答案:

答案 0 :(得分:1)

您可以将LIKE,REPLACE和TRIM函数组合使用。

select trim(':' from 
            replace(':'||your_column||':',':'||search_string||':',':')
           ) from table_name
 where ':'||your_column||':' like '%:'||search_string||':%';

想法是,

  • 用冒号环绕列,并使用LIKE函数查找匹配。
  • 在这些匹配的行上,使用REPLACE将搜索字符串与周围的冒号一起替换为单个冒号。
  • 然后使用TRIM删除周围的冒号。

sqlfiddle

演示

答案 1 :(得分:0)

编辑(简化)也许这就是你需要的:

SELECT REGEXP_REPLACE(REPLACE('abc:defg:klmnop', ':defg:', ':'), '(^defg:|:defg$)', '')
     , REGEXP_REPLACE(REPLACE('defg:klmnop:abc', ':defg:', ':'), '(^defg:|:defg$)', '')
     , REGEXP_REPLACE(REPLACE('abc:klmnop:defg', ':defg:', ':'), '(^defg:|:defg$)', '')
     , REGEXP_REPLACE(REPLACE('abc:klmnop:defgb:defg', ':defg:', ':'), '(^defg:|:defg$)', '')
  FROM DUAL
;

从开始,中间和结束中删除defg,并忽略defgb,给出:

  • ABC:klmnop
  • klmnop:ABC
  • ABC:klmnop
  • ABC:klmnop:defgb

要更新表格,您可以:

UPDATE my_table
   SET value = REGEXP_REPLACE(REGEXP_REPLACE(value, ':defg:', ':'), '(^defg:|:defg$)', '')
--  WHERE REGEXP_LIKE(value, '(^|.*:)defg(:.*|$)')
  WHERE value LIKE '%defg%'
;

(虽然最后的正则表达式可能需要调整以匹配,难以测试......)