Oracle 11g - REGEXP_REPLACE - Subexpressions/ различные совпадения
SQLFiddle: http://sqlfiddle.com/
Я работаю над запросом, который возвращает DN объекта:(cn=name,ou=folder,dc=hostname,dc=com)
Моя цель - вернуть эту информацию в более "симпатичном" виде, похожем на AD:(name\folder\hostname.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 --
Хотя это работает, я не в восторге от того, насколько это слишком сложно (и что это связано с необходимостью сшивать две строки regex'd).
Я начал с чистого листа и понял, что делаю слишком много, чтобы получить то, что хотел, и моя отправная точка сейчас здесь:
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
Ожидаемый результат
name\subgroup\group\accounts.hostname.com
name\group\hostname.com
Входящие данные являются динамическими и никогда не устанавливают количество OU или DC.
2 ответа
Вы можете использовать
SELECT REPLACE(
REGEXP_REPLACE(
test,
'(^|,)(cn|ou)=([^,]*)(,dc=)?',
'\3\\'),
',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 \2',1,1,'i')
, test
) , ' |,(CN|OU)=', '\\', 1, 0,'i'
), ',DC=', '.', 1, 0,'i'
),test) result
FROM regexTest
Этот запрос не меняет входные данные, если нет DC=
,