В системе я использую стандартный urn ( RFC8141 ) в качестве одного из полей. Из этой урны можно получить уникальный идентификатор. Странная вещь в урнах, описанных в RFC8141, заключается в том, что у вас может быть две разные урны, которые равны.
Чтобы проверить уникальные ключи, мне нужно извлечь разные части урны, которые составляют уникальный ключ. Для этого у меня есть это регулярное выражение ( регулярное выражение, которое соответствует URN по rfc8141 ):
\A(?i:urn:(?!urn:)(?<nid>[a-z0-9][a-z0-9-]{1,31}[^-]):(?<nss>(?:[-a-z0-9()+,.:=@;$_!*'&~\/]|%[0-9a-f]{2})+)(?:\?\+(?<rcomponent>.*?))?(?:\?=(?<qcomponent>.*?))?(?:#(?<fcomponent>.*?))?)\z
, что приводит к пяти именованным группам захвата (nid
, nss
, rcomponent
, qcomponent
en fcomponent
). Только nid
и nss
важны для проверки уникальности / равенства. Или: даже если компоненты изменяются, если nid
и nss
одинаковы, два элемента / записи равны (независимо от значений компонентов). nid
проверяется без учета регистра, nss
проверяется с учетом регистра.
Теперь, чтобы проверить уникальность / равенство, я определяю «очищенную урну», которая является первичным ключом. , Я добавил триггер, чтобы я мог извлечь различные группы захвата. Я хотел бы сделать следующее:
- извлечь
nid
и nss
(см. Регулярное выражение) из urn
- захватить их по имени. Здесь я не знаю, как это сделать: как я могу захватить эти две группы захвата в postgresql хранимой процедуре?
- добавить их как «очищенную урну», нижний регистр
nid
(чтобы иметь нечувствительность к регистру в этой части) и url-кодирование или url-декодирование строки (одно из двух, это не имеет значения, если оно согласовано). (Я также не уверен, есть ли функция кодирования / декодирования url в Postgres, но я задам другой вопрос, как только предыдущий будет решен :)).
Пример:
== РЕДАКТИРОВАТЬ 1: неназванные группы захвата ==
с неназванными группами захвата, это будет делаем то же самое:
select
g[2] as nid,
g[3] as nss,
g[4] as rcomp,
g[5] as qcomp,
g[6] as fcomp
from (
select regexp_matches('uRn:example:a123,z456?=xyz/something',
'\A(urn:(?!urn:)([a-z0-9][a-z0-9-]{1,31}[^-]):((?:[-a-z0-9()+,.:=@;$_!*''&~\/]|%[0-9a-f]{2})+)(?:\?\+(.*?))?(?:\?=(.*?))?(?:#(.*?))?)$', 'i')
g)
as ar;
(g[1]
- полное совпадение, которое мне не нужно)
Я обновил запрос:
- case нечувствительное сопоставление должно выполняться как флаг
- без групп захвата (postgres, похоже, возникают проблемы с именами групп захвата)
и делает выборку в массиве, разбивая массив на столбцы.