Вот запрос, который может отвечать всем требованиям, хотя он выходит за рамки определения проблемы и обрабатывает префиксы:
with names(name) as (
select 'LST, FRST MDL SR' from dual
union all select 'LST, FRST SR MDL MDL2' from dual
union all select 'LST, FRST MDL1 JR MDL2 MDL3' from dual
union all select 'Jones, John Paul' from dual
union all select 'Jones, Mr. John Jr Paul' from dual
union all select 'Jones, John Paul Jr Henry' from dual
union all select 'Henry, John Paul Sr' from dual
union all select 'Masters, Lee II' from dual
)
select name
, REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',3) pfx
, REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',5) frst
, rtrim(REGEXP_REPLACE(
REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',6)
,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)','\1',1,1,'i')) mdl
, REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',1) Lst
, REGEXP_SUBSTR(
REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',6)
,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)',1,1,'i',2) SFX
from names;
Если вы не хотите, чтобы префиксы работали, это может работатьyou:
select name
, REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',2) frst
, rtrim(REGEXP_REPLACE(
REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',3)
,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)','\1',1,1,'i')) mdl
, REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',1) Lst
, REGEXP_SUBSTR(
REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',3)
,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)',1,1,'i',2) SFX
from names;
Одно и то же регулярное выражение используется для идентификации и извлечения каждой части имени:
'([^,]+), ?([^ ]+) ?(.*)'
| | | | +--+ -> 3) Middle Names (including Suffix)
| | +-----+ -------> 2) First Name
+-----+ -----------------> 1) Last Name
Имя и фамилия являются прямыми.Средние имена и суффиксы, однако, требуют немного дополнительной работы для управления.Чтобы получить только вторые имена или суффикс, требуется второе регулярное выражение:
'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)'
Используя вышеприведенное регулярное выражение вместе с функцией REGEXP_REPLACE, суффикс можно удалить, оставив только вторые имена.Аналогично, используя то же регулярное выражение с функцией REGEXP_SUBSTR, можно получить сам суффикс.