首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >甲骨文中的Regex

甲骨文中的Regex
EN

Stack Overflow用户
提问于 2012-11-17 00:17:00
回答 3查看 1.2K关注 0票数 1

如何在Oracle中使用REGEXP_SUBSTR获取这些数据

代码语言:javascript
复制
SPRINTMVNO_PM_CDR_IWIRELESS_20121110_0813.csv get '08'in last four digits
RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt  get '0043722' in the middle(between'_')
wireless_201211120015_201211120515            get '0515' (last four digits)

我已经尝试过很多次了,但是有些表达式在PHP或其他语言中工作得很好,但在ORACLE中却不起作用。也许语法是不同的。

例如:我可以使用/(?<=_)[0-9]*(?=_)/获取php中的数字,但这在Oracle中行不通。

我试过了

代码语言:javascript
复制
SELECT REGEXP_SUBSTR('RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt','(?<=_)[0-9]*(?=_)') 
  FROM dual;

没有输出。所以这不是两条斜线的问题

这个问题的另一种表述是“如何在字符之间获取内容或以字符开头,但不包括,使用的正则表达式?”

我知道我可以通过使用字符串函数轻松地获得这些数据,问题是有很多不同的字符串需要处理,每个字符串都有不同的数据要检索。因此,我希望将模式存储到数据库中,并使用一个regexp_substr获取所有数据。否则我需要硬编码那些规则。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-17 08:42:20

Oracle从业者在没有正则表达式的情况下存活了多年,因为Oracle提供了一些简单的字符串函数,我们可以将这些函数组合起来进行一些巧妙的操作。

例如,要在字符串中找到最后下划线之后的前两个字符,请使用SUBSTR()和INSTR(),如下所示:

代码语言:javascript
复制
with t as (select 'SPRINTMVNO_PM_CDR_IWIRELESS_20121110_0813.csv' str from dual)
select substr(str, instr(str, '_', -1)+1, 2)
from t
/

注意,INSTR()调用有一个负偏移量,可以从后面开始计数。获取字符串的最后四个字符使用了相同的技巧:

代码语言:javascript
复制
with t as (select 'iwireless_201211120015_201211120515' str from dual)
select substr(str, -4)
from t
/

识别下划线模式的最简单方法是用正则表达式来识别下划线,后面跟着下划线,但是我们可以使用TRIM()从结果中删除下划线。

代码语言:javascript
复制
with t as (select 'RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt' str from dual)
select trim('_' from regexp_substr(str, '_([0-9]+)_'))
from t
/

下面是SQL Fiddle来证明这些技术是有效的。

Oracle有大量的函数,这些函数在文档中都有描述。了解更多信息

“请忽略这些情况,我只需要一个‘如何在字符之间获取内容或以字符开头,但不包括它,用Oracle的regex?’的解决方案?”

有一种方法可以从结果的开头或结尾排除字符,那就是将搜索模式分解为子表达式。这将适用于您提供的字符串,因为我们可以将前导和尾随下划线与所需的数字分开。不幸的是,子表达式参数是SUBSTR()签名,由于SQL函数不接受命名参数,这意味着我们必须显式地传递所有其他参数的默认值。

无论如何,此调用将返回第二个子表达式,即所需的字符串0043722

代码语言:javascript
复制
with t as (select 'RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt' str from dual)
select regexp_substr(str, '(_)([0-9]+)(_)', 1,1,'i',2)
from t
/

用例确实很重要。REGEXP函数的执行速度比简单的等效函数慢。在10gR2中,REGEXP_SUBSTR()至少比SUBSTR()慢一个数量级。当搜索大量字符串时,这种差异是显而易见的,而当这个数字变为数百万时,则会导致瘫痪(公开:最近的痛苦)。

票数 1
EN

Stack Overflow用户

发布于 2012-11-17 00:20:30

regex 周围的前导和尾部斜线与regex无关。

它们是perl/javascript语言仿制品。

试着不受刀痕的伤害

票数 1
EN

Stack Overflow用户

发布于 2012-11-17 01:59:39

Oracle使用POSIX ERE (扩展正则表达式)--除了添加反向引用这一值得注意的例外。但是POSIX在这里是非常有限的-它只需要很少的东西。尝试以下正则表达式:

代码语言:javascript
复制
/([0-9]{2}80|[0-9]80[0-9]|80[0-9]{2})$/

最后四位数就有80了。

代码语言:javascript
复制
/0515$/

最后四位数是0515。

现在,我从来没有使用过Oracle,所以我不知道您是否需要分隔符,但这两种方法都可以使用。中间的那个要复杂一些。如果你能接受“是的就在那里”,你应该能逃脱

代码语言:javascript
复制
/_0043722_/

但是,如果您需要提取它,您应该能够找到一些trim函数,它将允许您指定要修剪的内容。您不能使用Oracle中的正则表达式对其进行处理。

哦,如果您需要将所有这三个组合成一个正则表达式:

代码语言:javascript
复制
/([0-9]{2}80|[0-9]80[0-9]|80[0-9]{2}|0515)$|_0043722_/

如果将来需要Regex引用,请尝试本站

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13426316

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档