甲骨文 11g - REGEXP_REPLACE - 子表达式/不同匹配



SQLFiddle: http://sqlfiddle.com/#!4/db1bd/49/0

我正在处理一个返回对象 DN:(cn=name,ou=folder,dc=hostname,dc=com)的查询

我的目标是在类似于 AD 的"更漂亮"输出中返回此信息:(namefolderhostname.com)

我以一种笨拙的方式完成了这个:

REGEXP_REPLACE(REGEXP_REPLACE(TEST, '.*CN=(.+?),DC=.*', '1', 1, 1, 'i'), ',OU=', '', 1, 0, 'i') -- grab everything between CN= and DC=, replace with 's --
|| '' || 
REGEXP_REPLACE(SUBSTR(TEST, REGEXP_INSTR(TEST, ',DC=', 1, 1, 0, 'i')+4),',DC=','.', 1, 0, 'i') -- grab everything after DC=, replace with .'s --

虽然这有效,但我对它过于复杂并不感到兴奋(并且它涉及必须将两个正则表达式字符串缝合在一起)。

我开始干净,意识到我做得太多了,没有得到我想要的东西,我的起点现在在这里:

REGEXP_REPLACE(test, '(,?(cn=|ou=)(.+?),)', '3')

我想我对这个工作原理有很好的了解,但是如果我添加一个额外的 (...),它会破坏我已经工作的内容并返回整个字符串。 我读过 Oracle 的正则表达式引擎不如其他一些引擎先进,但我正在努力掌握如何评估事物的顺序。

示例输入(可以有多个 OU/DC):

cn=name,ou=subgroup,ou=group,dc=accounts,dc=hostname,dc=com cn=name,ou=group,dc=hostname,dc=com

预期输出

namesubgroupgroupaccounts.hostname.com namegrouphostname.com

传入的数据是动态的,永远不会有固定数量的 OU 或 DC。

您可以使用

SELECT REPLACE(
REGEXP_REPLACE(
test, 
'(^|,)(cn|ou)=([^,]*)(,dc=)?', 
'3\'), 
',dc=', 
'.') 
FROM regexTest

请参阅 SQLFiddle。

第一个正则表达式匹配字符串,或开头(^|,)(cn|ou)=([^,]*)(,dc=)?,然后匹配cnou,然后=,然后捕获到组中逗号以外的零个或多个字符,然后匹配可选的,dc=子字符串(因此,删除,dc=的第一个实例)。替换是组 3 内容和反斜杠。

因此,第二个操作很简单,只需将所有,dc=替换为.,您甚至不需要正则表达式即可。

可能是这样的:

SELECT nvl(regexp_replace(
regexp_replace(
nullif(
regexp_replace(test, '^cn=(.+?),DC=(.+?)$', '1 2',1,1,'i') 
, test
) , ' |,(CN|OU)=', '\', 1, 0,'i'
), ',DC=', '.', 1, 0,'i'
),test) result
FROM regexTest

如果没有DC=,则此查询不会更改输入。

最新更新