来自 CLOB 的 Oracle REGEXP_SUBSTR
Posted
技术标签:
【中文标题】来自 CLOB 的 Oracle REGEXP_SUBSTR【英文标题】:Oracle REGEXP_SUBSTR from CLOB 【发布时间】:2021-04-22 08:48:29 【问题描述】:我正在尝试从我的数据库中的 CLOB 字段中查找子字符串。
考虑以下字符串:
someothertext 2. Grad Dekubitus (Druckgeschwür) mit Abschürfung/Blase/Hautverlust someothertext
我只想从字符串中提取 "2.Grad",但我的正则表达式似乎不起作用 - 我在一些在线正则表达式检查器中对字符串进行了测试,结果确实如此实际工作(Fiddle)
这是我的正则表达式:
REGEXP_SUBSTR(DBMS_LOB.SUBSTR(cf.TEXT, 4000), '\b[0-9]\.\sGrad$') AS "Grad"
目前,它返回 NULL,但我不知道为什么。
关于如何让它发挥作用的任何想法?
【问题讨论】:
尝试不使用锚$
Oracel 正则表达式不支持单词边界。 [0-9]\.\sGrad
将工作。或者,(^|\D)([0-9]\.\sGrad)
,如果您需要确保[0-9]
之前没有数字。
根据documentation REGEXP_SUBSTR
也适用于CLOB
,即您不必转换为VARCHAR2
@WernfriedDomscheit 对我来说它不起作用,如果我不转换它,我会收到以下错误:ORA-00932:不一致的数据类型:预期 - 得到 CLOB
好吧,没关系。也许是文档错误。或者你有一个旧的 Oracle。
【参考方案1】:
Oracle 不支持正则表达式中的字边界\b
。
如果您希望数字前有空格,请删除 \b
或将其替换为 (^|\s)
。
您还需要删除结尾的$
,因为此时您并没有尝试匹配字符串的结尾。
REGEXP_SUBSTR( DBMS_LOB.SUBSTR(cf.TEXT, 4000), '(^|\s)[0-9]\.\sGrad' ) AS "Grad"
此外,如果您可以拥有多位数字,那么您可能需要使用[0-9]+
。
如果您不想要前导空格,则可以将表达式的第二部分包装在捕获组中,然后使用 REGEXP_SUBSTR
的第 6 个参数提取该捕获组的值:
REGEXP_SUBSTR(
DBMS_LOB.SUBSTR(cf.TEXT, 4000),
'(^|\s)([0-9]\.\sGrad)',
1, -- Start from the 1st character
1, -- Find the 1st occurrence
NULL, -- No flags
2 -- Return the 2nd capturing group
) AS "Grad"
【讨论】:
感谢捕获组的提示,我还不是正则表达式方面的专家,这很有帮助!也感谢您的精彩解释:)。【参考方案2】:Oracle 正则表达式不支持单词边界。此外,$
在您的模式中是多余的(请注意,您不要在正则表达式演示中使用它)。
你可以使用
REGEXP_SUBSTR(
'someothertext 2. Grad Dekubitus (Druckgeschwür) mit Abschürfung/Blase/Hautverlust someothertext',
'(^|\D)([0-9]\.\sGrad)', 1, 1, NULL, 2
) AS "Grad"
在哪里
(^|\D)
- 第 1 组:字符串或非数字开头
([0-9]\.\sGrad)
- 第 2 组:一个数字、一个点、作为空格和 Grad
如果与[0-9]
匹配的数字前面应该有空格,您可以将(^|\D)
替换为(\s|^)
。
【讨论】:
您好 Wiktor,我不知道 Oracle 正则表达式不支持此功能,感谢您的快速帮助,它现在可以工作了 :)。 @Max Word 边界是危险的,因为它们的含义取决于上下文。我在这里建议一个数字和一个空白边界,请选择最适合你的。 @Max1, 1, NULL, 2
代表从字符串中的第一个字符开始寻找匹配(1
),返回第一个匹配 i> (1
),不传递其他标志 (NULL
),并且返回的字符串必须是第 2 组值 (2
)。以上是关于来自 CLOB 的 Oracle REGEXP_SUBSTR的主要内容,如果未能解决你的问题,请参考以下文章