如何在Oracle中使用REGEXP_SUBSTR获取这些数据
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中行不通。
我试过了
SELECT REGEXP_SUBSTR('RK_IPDR_RKMSG2_0043722_DT_20121113162710.txt','(?<=_)[0-9]*(?=_)')
FROM dual;没有输出。所以这不是两条斜线的问题
这个问题的另一种表述是“如何在字符之间获取内容或以字符开头,但不包括,使用的正则表达式?”
我知道我可以通过使用字符串函数轻松地获得这些数据,问题是有很多不同的字符串需要处理,每个字符串都有不同的数据要检索。因此,我希望将模式存储到数据库中,并使用一个regexp_substr获取所有数据。否则我需要硬编码那些规则。
发布于 2012-11-17 08:42:20
Oracle从业者在没有正则表达式的情况下存活了多年,因为Oracle提供了一些简单的字符串函数,我们可以将这些函数组合起来进行一些巧妙的操作。
例如,要在字符串中找到最后下划线之后的前两个字符,请使用SUBSTR()和INSTR(),如下所示:
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()调用有一个负偏移量,可以从后面开始计数。获取字符串的最后四个字符使用了相同的技巧:
with t as (select 'iwireless_201211120015_201211120515' str from dual)
select substr(str, -4)
from t
/识别下划线模式的最简单方法是用正则表达式来识别下划线,后面跟着下划线,但是我们可以使用TRIM()从结果中删除下划线。
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。
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()慢一个数量级。当搜索大量字符串时,这种差异是显而易见的,而当这个数字变为数百万时,则会导致瘫痪(公开:最近的痛苦)。
发布于 2012-11-17 00:20:30
regex 周围的前导和尾部斜线与regex无关。
它们是perl/javascript语言仿制品。
试着不受刀痕的伤害
发布于 2012-11-17 01:59:39
Oracle使用POSIX ERE (扩展正则表达式)--除了添加反向引用这一值得注意的例外。但是POSIX在这里是非常有限的-它只需要很少的东西。尝试以下正则表达式:
/([0-9]{2}80|[0-9]80[0-9]|80[0-9]{2})$/最后四位数就有80了。
/0515$/最后四位数是0515。
现在,我从来没有使用过Oracle,所以我不知道您是否需要分隔符,但这两种方法都可以使用。中间的那个要复杂一些。如果你能接受“是的就在那里”,你应该能逃脱
/_0043722_/但是,如果您需要提取它,您应该能够找到一些trim函数,它将允许您指定要修剪的内容。您不能使用Oracle中的正则表达式对其进行处理。
哦,如果您需要将所有这三个组合成一个正则表达式:
/([0-9]{2}80|[0-9]80[0-9]|80[0-9]{2}|0515)$|_0043722_/如果将来需要Regex引用,请尝试本站。
https://stackoverflow.com/questions/13426316
复制相似问题