如何扩展以下正则表达式(在 POSIX 标准中)以使值,, ;, /, , 即 逗号、分号、斜杠、空格和制表符的组合。
初始数据示例:
ID EMAIL
-- --------------------------------------------------
1 NULL
2 mail1@domain.com
3 mail1@domain.com; mail2@domain.com, mail3@mail.com
4 mail1@domain.com, mail2@domain.com
5 mail1@domain.com mail2@domain.com
在 这封DB Fiddle邮件中,我尝试从每一行中提取第二封电子邮件,并希望得到以下结果(输出数据集):
ID EMAIL
-- --------------------------------------------------
1 NULL
2 NULL
3 mail2@domain.com
4 mail2@domain.com
5 mail2@domain.com
那些。结果不应该包含分隔符:,, ;, /,
我尝试添加一个 POSIX 值[:space:]来处理空格和制表符,但结果是错误的:
select
id,
regexp_substr (email, '(.*?)(([[:space:],;/])|($))', 1, 2, null, 1) as second_email
from tab;
ID EMAIL
-- --------------------------------------------------
1 NULL
2 NULL
3 NULL
4 NULL
5 mail2@domain.com
请告诉我如何修复 POSIX RegEx。
注意:我正在使用 Oracle 12.2,它不理解 RegEx 字符\s,所以我只需要使用 POSIX 标准支持的正则表达式。
PS 在这个例子中,我总是从字符串中提取第二个值——这是一个简化的(最小可重现的)例子。事实上,这是函数的一部分,它应该能够提取任何第 N 个值(N它将作为参数传递给函数)。
看起来以下正则表达式有效:
两个输出:
https://dbfiddle.uk/?rdbms=oracle_18&fiddle=182ab5331fc09c25ab534002c56c634f
正则表达式
(.*?)(([[:space:],;/])|($))并不总能找到所需的匹配项,因为它(.*?)还会找到一个空字符串,并且在您的行中,分隔符旁边有空白字符,[[:space:],;/]它会找到它们。换句话说,它(.*?)捕获一个空字符串,而不是所需的值,[[:space:],;/]在例如逗号之后找到一个空格,然后返回一个匹配项。因此,
(.*?)您需要替换这样的模板,以便它找不到空字符串,例如(我对所有子模式都使用了原始语法,但我不确定这里是否需要它们。)
该模式
([^[:space:]].*?)将找不到空字符串,因为它[^[:space:]]需要除空格之外的任何一个字符,并且匹配将从该字符开始。