我使用积极的lookbehind写了一个正则表达式,但Oracle不能使用lookbehinds,所以我有点不知所措。
//test string without suffix
Last_name, First_name Middle_initial:(some_other_unimportant_stuff)
//test string with suffix
Last_name Suffix, First_name Middle_initial:(some_other_unimportant_stuff)
我正在尝试使用以下查询从表中解析一些数据:
SELECT
regexp_substr(displayname,'[^,]*') AS last_name,
regexp_substr(displayname,'(?<=,)[^\]]+\s') AS first_name,
upper(substr(regexp_substr(displayname,'[A-Za-z]:'),0,1)) AS middle_initial
FROM table
我可以获得last_name
和middle initial
,但first_name
会导致我出现问题。有关如何重写正则表达式以获取名字,或使用oracle函数中的烘焙来完成同样的事情的任何想法? TIA
答案 0 :(得分:1)
Oracle正则表达式不支持外观。但是,您可以使用捕获组并访问其值:
regexp_substr(au.displayname, ',\s*([A-Za-z]+)\s', 1, 1, NULL, 1) AS first_name
此处,捕获组定义为(....)
,最后1
告诉regexp_substr
仅输出此子值。
以下是how this regex works(我添加了_
以匹配OP中提供的占位符。
答案 1 :(得分:1)
这是一种方法,可以使正则表达式相同,从而更容易维护。通过对它们进行分组将该行分解为它的组件,然后为每个元素选择所需的组。请注意,分隔符未分组。如果first_name中有空格,它将无法工作。
SQL> with tbl(str) as (
select 'Last_name, First_name Middle_initial:(some_other_unimportant_stuff)' from dual union
select 'Last_name Suffix, First_name Middle_initial:(some_other_unimportant_stuff)' from dual
)
select regexp_substr(str, '(.*?), (.*?) (.*?):', 1, 1, NULL, 1) Last,
regexp_substr(str, '(.*?), (.*?) (.*?):', 1, 1, NULL, 2) First,
regexp_substr(str, '(.*?), (.*?) (.*?):', 1, 1, NULL, 3) Middle
from tbl;
LAST FIRST MIDDLE
------------------ --------------- ---------------
Last_name Suffix First_name Middle_initial
Last_name First_name Middle_initial
SQL>
编辑:根据新名称要求更新。我废弃了正则表达式都是相同的,而是通过将它们固定在字符串的开头来将它们收紧一些。对于姓氏,返回组后跟逗号空格。名字是由逗号空格和空格包围的组,最后,中间名称是由最后一个空格和冒号包围的字符组。问号使组成为可选组,因此它应该处理测试数据中看到的NULL名字。像往常一样,测试意外!
SQL> with tbl(str) as (
select 'Last_name, First_name Middle_initial:(some_other_unimportant_stuff)' from dual union
select 'Last_name Suffix, First_name Middle_initial:(some_other_unimportant_stuff)' from dual union
select 'Doe1, D John:(...)' from dual union
select 'Doe2, John D James:(...)' from dual union
select 'Doe3, Jane:(...)' from dual
)
select regexp_substr(str, '^(.*?), ', 1, 1, NULL, 1) Last,
regexp_substr(str, '^.*, (.*?) ', 1, 1, NULL, 1) First,
regexp_substr(str, '^.* (.*?):', 1, 1, NULL, 1) Middle
from tbl;
LAST FIRST MIDDLE
------------------ --------------- ---------------
Doe1 D John
Doe2 John D James
Doe3 Jane
Last_name Suffix First_name Middle_initial
Last_name First_name Middle_initial
SQL>
答案 2 :(得分:0)
这就是我提出的:
//the regex for First_name
\s[A-Za-z]+
让我
, First_name
查询现在看起来像:
SELECT
regexp_substr(displayname,'[^,]*') AS last_name,
trim(substr(regexp_substr(au.displayname,',\s[A-Za-z]+'),2)) AS first_name,
upper(substr(regexp_substr(displayname,'[A-Za-z]:'),0,1)) AS middle_initial
FROM table