Oracle 11g - REGEXP_REPLACE - Subexpressions/different 匹配
Oracle 11g - REGEXP_REPLACE - Subexpressions/different matches
SQLFiddle:http://sqlfiddle.com/#!4/db1bd/49/0
我正在处理 return 对象 DN 的查询:(cn=name,ou=folder,dc=hostname,dc=com)
我的目标是 return 在类似于 AD 的 "prettier" 输出中输出此信息:(name\folder\hostname.com)
我用笨拙的方式完成了这个:
REGEXP_REPLACE(REGEXP_REPLACE(TEST, '.*CN=(.+?),DC=.*', '', 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=)(.+?),)', '\')
我认为我很清楚这个是如何工作的,但是如果我添加一个额外的 (...) 它会破坏我已经在工作的东西 return 是整个字符串。我读到 Oracle 的正则表达式引擎不如其他引擎先进,但我正在努力掌握事物的评估顺序。
示例输入(可以有多个OUs/DCs):
cn=name,ou=subgroup,ou=group,dc=accounts,dc=hostname,dc=com
cn=name,ou=group,dc=hostname,dc=com
预期输出
name\subgroup\group\accounts.hostname.com
name\group\hostname.com
传入的数据是动态的,从来没有固定数量的 OU 或 DC。
您可以使用
SELECT REPLACE(
REGEXP_REPLACE(
test,
'(^|,)(cn|ou)=([^,]*)(,dc=)?',
'\'),
',dc=',
'.')
FROM regexTest
参见SQLFiddle。
第一个 (^|,)(cn|ou)=([^,]*)(,dc=)?
正则表达式匹配 ,
或字符串的开头,然后是 cn
或 ou
,然后是 =
,然后捕获到第 3 组零或除逗号以外的更多字符,然后匹配可选的 ,dc=
子字符串(因此,删除 ,dc=
的第一个实例)。替换为第 3 组内容和一个反斜杠。
所以,第二个操作很简单,只需将所有,dc=
替换为.
,你甚至不需要正则表达式。
可能是这样的:
SELECT nvl(regexp_replace(
regexp_replace(
nullif(
regexp_replace(test, '^cn=(.+?),DC=(.+?)$', ' ',1,1,'i')
, test
) , ' |,(CN|OU)=', '\', 1, 0,'i'
), ',DC=', '.', 1, 0,'i'
),test) result
FROM regexTest
如果没有DC=
,则此查询不会更改输入。
SQLFiddle:http://sqlfiddle.com/#!4/db1bd/49/0
我正在处理 return 对象 DN 的查询:(cn=name,ou=folder,dc=hostname,dc=com)
我的目标是 return 在类似于 AD 的 "prettier" 输出中输出此信息:(name\folder\hostname.com)
我用笨拙的方式完成了这个:
REGEXP_REPLACE(REGEXP_REPLACE(TEST, '.*CN=(.+?),DC=.*', '', 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=)(.+?),)', '\')
我认为我很清楚这个是如何工作的,但是如果我添加一个额外的 (...) 它会破坏我已经在工作的东西 return 是整个字符串。我读到 Oracle 的正则表达式引擎不如其他引擎先进,但我正在努力掌握事物的评估顺序。
示例输入(可以有多个OUs/DCs):
cn=name,ou=subgroup,ou=group,dc=accounts,dc=hostname,dc=com
cn=name,ou=group,dc=hostname,dc=com
预期输出
name\subgroup\group\accounts.hostname.com
name\group\hostname.com
传入的数据是动态的,从来没有固定数量的 OU 或 DC。
您可以使用
SELECT REPLACE(
REGEXP_REPLACE(
test,
'(^|,)(cn|ou)=([^,]*)(,dc=)?',
'\'),
',dc=',
'.')
FROM regexTest
参见SQLFiddle。
第一个 (^|,)(cn|ou)=([^,]*)(,dc=)?
正则表达式匹配 ,
或字符串的开头,然后是 cn
或 ou
,然后是 =
,然后捕获到第 3 组零或除逗号以外的更多字符,然后匹配可选的 ,dc=
子字符串(因此,删除 ,dc=
的第一个实例)。替换为第 3 组内容和一个反斜杠。
所以,第二个操作很简单,只需将所有,dc=
替换为.
,你甚至不需要正则表达式。
可能是这样的:
SELECT nvl(regexp_replace(
regexp_replace(
nullif(
regexp_replace(test, '^cn=(.+?),DC=(.+?)$', ' ',1,1,'i')
, test
) , ' |,(CN|OU)=', '\', 1, 0,'i'
), ',DC=', '.', 1, 0,'i'
),test) result
FROM regexTest
如果没有DC=
,则此查询不会更改输入。