Oracle 11g中的变量元素字符串匹配

时间:2017-05-05 18:43:22

标签: regex oracle

我使用积极的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_namemiddle initial,但first_name会导致我出现问题。有关如何重写正则表达式以获取名字,或使用oracle函数中的烘焙来完成同样的事情的任何想法? TIA

3 个答案:

答案 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