【问题标题】:Oracle SQL: Extracting text between two charactersOracle SQL:提取两个字符之间的文本
【发布时间】:2018-10-04 21:12:16
【问题描述】:

我的字符串看起来像

{ABCDE}{F1}
{GHIJ}{K12}

我想提取第一个大括号之间的文本

ABCDE
GHIJ

我尝试在线搜索,但很多答案似乎是使用函数或 PL-SQL。有人可以帮我解决这个问题吗?

【问题讨论】:

  • 阅读正则表达式。

标签: sql regex oracle substring


【解决方案1】:

我们可以在这里使用REGEXP_SUBSTR

SELECT regexp_substr('{ABCDE}{F1}', '\{([^}]+)\}', 1,1,NULL,1) AS output
FROM dual

Demo

这是REGEXP_SUBSTR 的一种不太常见的用法,它使用捕获组,按照这种模式:

\{([^}]+)\}

第六个参数表示返回第一个捕获组。

【讨论】:

  • 我认为正则表达式中的最后一个\} 是不必要的
  • @DavidFaber 是的,因为该列中的某些值可能没有右括号,在这种情况下我们可能不想捕获它们。这取决于我们对 OP 数据的假设。我倾向于安全行事。
  • 很好的答案,但你的意思是第六个参数而不是第四个?我拿了你的代码,让它适用于示例中的第二个字符串: regexp_substr(raw_text, '\{([^}]+)\}', 1,2,NULL,1)
  • @ChristianPalmer 也许重新加载您的页面以查看 OP 的实际数据是什么样的。您在查询中从 1 更改为 2 的第四个参数只是表示采用第二个匹配项,而不是第一个匹配项。如果我没看错的话,这不是 OP 想要的。
  • @TimBiegeleisen - 你是对的 - 我跟上世界的步伐太慢了:)
【解决方案2】:

这是老派。我喜欢正则表达式并且可以理解它们,但是当我尝试生成它们时遇到了很多麻烦。有点像西班牙语(对我来说)。所以这只是 SQL INSTR / SUBSTR / REPLACE。我不期待任何支持...

WITH test_data (raw_text)
 AS 
  (SELECT '{ABCDE}{F1}' from dual UNION ALL
   SELECT '{GHIJ}{K12}' from dual 
  )
SELECT
 raw_text
,SUBSTR(raw_text,2,INSTR(raw_text,'}{')-2)              first_string
,REPLACE(SUBSTR(raw_text,INSTR(raw_text,'}{')+2),'}')   second_string
--these two from Tim's excellent answer
,regexp_substr(raw_text, '\{([^}]+)\}', 1,1,NULL,1) 
,regexp_substr(raw_text, '\{([^}]+)\}', 1,2,NULL,1)
FROM
 test_data
;

Demo

【讨论】:

  • 实际上,使用基本字符串函数通常优于正则表达式,至少对于像这样的简单操作。但是,它的缺点是代码更难阅读,并且可能难以维护 +1。
【解决方案3】:

您可以尝试以下方法:

SELECT TRIM( '{' FROM REGEXP_SUBSTR(mystring, '\{[^}]+') )
  FROM mytable;

这将捕获从第一个左大括号到但不包括右大括号的文本,然后从结果中修剪左大括号。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2014-03-26
    • 2018-11-02
    • 2019-07-02
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 2016-08-13
    • 2013-05-14
    相关资源
    最近更新 更多