【问题标题】:Oracle PL/SQL regexp_replace for multiple wordsOracle PL/SQL regexp_replace 用于多个单词
【发布时间】:2016-08-31 15:54:47
【问题描述】:

我有一个字符串 'TICKER: IBM IBM Corporation Inc.'我想删除代码和它的值,只在 Oracle PL/SQL 中获取剩余的值。

所以我做了这个查询,但它没有按照我的预期工作:

SELECT REGEXP_REPLACE(
           'TICKER: IBM IBM Corporation Inc.',
           '(.*):[[:space:]](.*)[[:space:]](.*)', '\3')
      FROM dual;

我希望 '\3' 会产生 'IBM Corporation Inc.'但我得到的只是“公司”。结果。

REGEXP_REPLACE('TICKER:IBMIBMCORPORATIONINC.','(.*):[[:SPACE:]](.*)[[:SPACE:]](.*)','\3') 
----------------------------------------------------------------------------- 
Inc.                                                                                      

1 rows selected

更新:

SELECT REGEXP_REPLACE(
       'TICKER: IBM IBM Corporation Inc.',
       '(.*):[[:space:]](.*)[[:space:]](.*)', '\1|\2|\3')
  FROM dual;

结果:

REGEXP_REPLACE('TICKER:IBMIBMCORPORATIONINC.','(.*):[[:SPACE:]](.*)[[:SPACE:]](.*)','\1|\2|\3') 
-------------------------------------------------------------------------------- 
TICKER|IBM IBM Corporation|Inc.

我在正则表达式中遗漏了什么?

谢谢。

【问题讨论】:

标签: oracle regexp-replace


【解决方案1】:
SELECT REGEXP_REPLACE(
       'TICKER: IBM IBM Corporation Inc.',
       '(.*):[[:space:]]([^ ]*)[[:space:]](.*)', '\3')
  FROM dual;

你的第二个捕捉表达是抓住一切,包括下一个空间。

我应该提到我在 Oracle 中测试过,而不是 PL/SQL。不过我认为没有区别。

PS:以下替代方法也可以:

-- using only one capturing expression
SELECT REGEXP_REPLACE(
       'TICKER: IBM IBM Corporation Inc.',
       '.*: [^ ]* (.*)', '\1')
  FROM dual;

  -- using no capturing expressions
  SELECT REGEXP_REPLACE(
       'TICKER: IBM IBM Corporation Inc.',
       '.*: [^ ]* ', '')
  FROM dual;

【讨论】:

  • 我正在考虑用 NULL 替换前 2 个单词,假设它们始终存在并且值(符号?)将始终为 1 个单词):'\w+: \w+ '
  • 应该通过锚定到字符串的开头将其收紧一点:'^\w+: \w+ '
【解决方案2】:
SELECT REGEXP_REPLACE(
           'TICKER: IBM IBM Corporation Inc.',
           '^(.*?):\s(\S*)\s(.*)$',
           '\3'
       )
FROM DUAL;

或者,您的代码不需要进行很多更改即可使其工作(将其锚定到字符串的开头并将前两个通配符匹配转换为非贪婪):

SELECT REGEXP_REPLACE(
           'TICKER: IBM IBM: Corporation Inc.',
           '^(.*?):[[:space:]](.*?)[[:space:]](.*)',
           '\3'
        )
FROM DUAL;

【讨论】:

  • 不太可能,但永远不会知道,尝试使用包含冒号的公司名称:'TICKER: IBM :IBM Co:rporation: Inc.'。我猜应该首先运行一个查询来检查数据中的冒号。
  • 关于包含冒号的描述的要点。您的查询似乎处理得很好。谢谢。 +1
  • @JKK 总是期待意外!根据数据的来源以及验证(或很可能没有)验证的程度,可以接受各种杂乱无章的数据并最终进入数据库。在做出诸如“公司名称永远不会包含冒号”之类的假设之前,请务必对数据进行一些完整性检查:-)
  • 是的,同意。在我的场景中,这些数据总是得到很好的维护(因为它是由另一层制作的)并且没有任何非字母或特殊字符。话虽如此,我将采用建议的方法(以防万一)。谢谢。
  • @JKK 修复了 : 问题,并为您的原始查询添加了一个简单的修复程序。
猜你喜欢
  • 2016-06-13
  • 2021-03-22
  • 1970-01-01
  • 2018-08-05
  • 2018-09-20
  • 2021-10-05
  • 2018-10-07
  • 2020-01-21
  • 1970-01-01
相关资源
最近更新 更多