Sql REGEXP Oracle几个not语句
我有一个字符串,有4个名字,用逗号分隔。4个名称中有3个内部有严格的标识符,最后一个没有标识符。字符串中名称的顺序是随机的。如何使用oracle REGEXP获得没有标识符的名称 示例字符串:“a。名字1,b。名称2,名称3,c-f名称4' 严格标识符为“a.”、“b.”、“c-f” 名称1、名称2和名称4我可以通过以下方式获得:Sql REGEXP Oracle几个not语句,sql,regex,oracle,Sql,Regex,Oracle,我有一个字符串,有4个名字,用逗号分隔。4个名称中有3个内部有严格的标识符,最后一个没有标识符。字符串中名称的顺序是随机的。如何使用oracle REGEXP获得没有标识符的名称 示例字符串:“a。名字1,b。名称2,名称3,c-f名称4' 严格标识符为“a.”、“b.”、“c-f” 名称1、名称2和名称4我可以通过以下方式获得: select regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )a.[^,]+($|,)')
select
regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )a.[^,]+($|,)') as name1,
regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )b.[^,]+($|,)') as name2,
regexp_substr('a. Name1, b. Name2, Name3, c-f Name4','(^|, )c\-f[^,]+($|,)') as name4
from dual
我想通过这样的方式获得name3:
'(^|, )((NOT("a."))and(NOT("b."))and(NOT("c-f")))([^,]+($|,)'
但我不知道如何使用REGEXP。在Oracle中是否可能?这将匹配第三个背面引用括号中的任何图案
REGEXP_REPLACE(
yourStringColumn,
'a\. (.*), b\. (.*), (.*), c-f (.*)',
'\3'
)
我使用的模式中有4个反向引用,每个都是您要查找的名称。背面参照之外的模式的其余部分是您描述的模式的固定部分。只要记住避开句号,这样它就不会被当作通配符“\”
编辑:
如果它们可以是任意顺序,我最好的尝试是在逗号或字符串的开始/结束之间找到一个项目,该项目本身不包含逗号或空格,空格表示有前缀
SELECT
regexp_replace(
'c-f Name1, Name2, b. Name3, a. Name4',
'(^|.+, )([^, ]+)($|, .+)',
'\2'
)
FROM
dual
;
它必须是正则表达式吗?因为,如果没有,SUBSTR+INSTR组合也会起作用
SQL> with test (col) as
2 (select 'a. Name1, b. Name2, Name3, c-f Name4' from dual)
3 select
4 trim(substr(col, instr(col, '.', 1, 1) + 1,
5 instr(col, ',', 1, 1) - instr(col, '.', 1, 1) - 1)) str1,
6 trim(substr(col, instr(col, '.', 1, 2) + 1,
7 instr(col, ',', 1, 2) - instr(col, '.', 1, 2) - 1)) str2,
8 trim(substr(col, instr(col, ',', 1, 2) + 1,
9 instr(col, ',', 1, 3) - instr(col, ',', 1, 2) - 1)) str3,
10 trim(substr(col, instr(col, 'c-f', 1, 1) + 4)) str4
11 from test;
STR1 STR2 STR3 STR4
----- ----- ----- -----
Name1 Name2 Name3 Name4
SQL>
[根据MatBailie的评论编辑]
SQL> with test (col) as
2 (select 'a. Name1, b. Name2, Name3, c-f Name4' from dual)
3 select
4 trim(substr(col, instr(col, 'a.', 1, 1) + 2,
5 instr(col, ', b.', 1, 1) - instr(col, 'a.', 1, 1) - 2)) str1,
6 trim(substr(col, instr(col, 'b.', 1, 1) + 2,
7 instr(col, ',', 1, 2) - instr(col, 'b.', 1, 1) - 2)) str2,
8 trim(substr(col, instr(col, ',', 1, 2) + 1,
9 instr(col, ',', 1, 3) - instr(col, ',', 1, 2) - 1)) str3,
10 trim(substr(col, instr(col, 'c-f', 1, 1) + 4)) str4
11 from test;
STR1 STR2 STR3 STR4
----- ----- ----- -----
Name1 Name2 Name3 Name4
SQL>
[编辑2]
既然标识符可以放在任何地方,那么这样的代码呢
SQL> with test (col) as
2 (select 'a. Little foot, c-f Bruce Wayne, Catherine Zeta-Jones, b. Bill White Jr.' from dual),
3 inter as
4 (select trim(regexp_substr(col, '[^,]+', 1, level)) str
5 from test
6 connect by level <= regexp_count(col, ',') + 1
7 ),
8 inter2 as
9 (select trim(replace(replace(replace(str, 'a.', ''),
10 'b.', ''),
11 'c-f', '')) result,
12 rownum rn
13 from inter
14 )
15 select max(decode(rn, 1, result)) n1,
16 max(decode(rn, 2, result)) n2,
17 max(decode(rn, 3, result)) n3,
18 max(decode(rn, 4, result)) n4
19 from inter2;
N1 N2 N3 N4
-------------------- -------------------- -------------------- --------------------
Little foot Bruce Wayne Catherine Zeta-Jones Bill White Jr.
SQL>
我知道我可以多次使用REGEXP_REPLACE函数:
select
regexp_replace(
regexp_replace(
regexp_replace(
'a. Name1, b. Name2, Name3, c-f Name4',
'(^|, | )a\.[^,]+($|,)'),
'(^|, | )b\.[^,]+($|,)'),
'(^|, | )c\-f[^,]+($|,)') as name3
from dual
谢谢你,MatBailie,使用REGEXP\u替换的想法 注意名字不包含句号等。根据我的经验,最好是搜索完整的'b'字符串中的名称顺序是随机的,例如,它可以是“b”。名字2,名字3,c-f名字4,a。名称1'这些名称实际上包含什么?是否有点、逗号、破折号等,或者这些只是字母数字?我已经发布了另一个示例代码编辑2;请看一看。从Op的评论来看,这不是一个分门别类的问题,也不是找到第三项的问题。这是一种寻找一个在开始时没有“a.”或“b.”或“c-f”的项目的情况,而不知道该项目在列表中的位置;它们对a、b和c-f没有问题,但对第四个值有问题……字符串中名称的顺序是随机的,例如“b”。名字2,名字3,c-f名字4,a。名称1’。所以它并不总是字符串中的第三位。@Room'on希望简化的建议有帮助吗?谢谢你的建议,但在我的例子中,Name3也可以包含空格…如果没有lookahead,我认为oracle不直接支持它,我认为not/and模式是不可能的。你需要找到一种更具创造性的方法。是的,没有lookaheads是无法否定一系列字符的。在一些外来的正则表达式风格中还有其他的构造,Oracle正则表达式不是其中之一。如何定义“严格标识符”?True或false:您可以通过注意模式逗号空格、非空格、非逗号字符(逗号?)来识别没有严格标识符的名称?其中,前导的“逗号空格”可以是“字符串的开始”,和/或尾随的逗号可以是“字符串的结束”?似乎是这样。如果这是正确的,它还会直接告诉你如何编写正则表达式。@mathguy我需要这样的东西:“^ |,NOTa.andNOTb.andNOTc-f[^,]+$,“@Room”on-你没有回答我的问题,关于如何在没有严格标识符的情况下识别名称。写一个只硬编码几个特定标识符的解决方案是没有意义的;如果你硬编码a。和b。对于像t这样的输入,查询将不能按需要工作。名字,好吗?