在ORACLE中第n次出现管道|
符号后,获取字符或字符串的正则表达式查询是什么?例如,我有两个字符串,如下所示,
Jack|Sparrow|17-09-16|DY7009|Address at some where|details
|Jack|Sparrow|17-09-16||Address at some where|details
我想要' DY7009'在第3个管道符号从第1个位置开始之后,那么正则表达式查询是什么?并且在第二个字符串中假设第一个位置具有|
符号,那么如果没有值,我想要第四个字符串,那么它应该给出NULL或BLANK值。
select regexp_substr('Jack|Sparrow|17-09-16|DY7009|Address at some where|details'
,' ?? --REX Exp-- ?? ') as col
from dual;
结果 - DY7009
select regexp_substr('Jack|Sparrow|17-09-16|DY7009|Address at some where|details'
,' ?? --REX Exp-- ?? ') as col
from dual;
结果 - ''或(即NULL)
那么正则表达式应该是什么?请帮忙。提前谢谢
谢谢大家!!,谢谢你的回答!!我想,我没有问问题。我只想要一个正则表达式来获得'字符串/字符串'在第n次出现管道符号后。我不想替换任何字符串,所以只有regexp_substr才能完成这项工作。
---->如果'杰克|麻雀| SQY778 | 17JULY17 || 00J1'是一个字符串
我想在第二个管线符号后面找到字符串值,答案是SQY778。如果我想在第3个管道符号后找到字符串,那么答案将是17JULY17。如果我想在第4个管道符号之后找到值,那么它应该给出BLANK或NULL值,因为在第4个管道符号之后没有任何内容。如果我想找到字符串第5个符号,那么我只会替换正则表达式中的一个数字,即5,因此我将获得00J1。
答案 0 :(得分:3)
你去吧。将regexp_substr()的第四个参数替换为所需字段的编号。
with tbl(str) as (
select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' from dual
)
select regexp_substr(str, '(.*?)(\||$)', 1, 4, NULL, 1) field_4
from tbl;
FIELD_4
--------
DY7009
SQL>
列出所有字段:
with tbl(str) as (
select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' from dual
)
select regexp_substr(str, '(.*?)(\||$)', 1, level, NULL, 1) split
from tbl
connect by level <= regexp_count(str, '\|')+1;
SPLIT
-------------------------
Jack
Sparrow
17-09-16
DY7009
Address at some where
details
6 rows selected.
SQL>
因此,如果您想要使用选择字段:
with tbl(str) as (
select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' from dual
)
select
regexp_substr(str, '(.*?)(\||$)', 1, 1, NULL, 1) first,
regexp_substr(str, '(.*?)(\||$)', 1, 2, NULL, 1) second,
regexp_substr(str, '(.*?)(\||$)', 1, 3, NULL, 1) third,
regexp_substr(str, '(.*?)(\||$)', 1, 4, NULL, 1) fourth
from tbl;
请注意,此正则表达式处理NULL元素,仍将返回正确的值。其他一些答案使用'[^|]+'
形式来解析字符串,但是当存在NULL元素时应该避免这种情况。请参阅此处以获取证明:https://stackoverflow.com/a/31464699/2543416
答案 1 :(得分:0)
您可以使用regex_replace获取第n个匹配组。在您的示例中,可以像这样检索第四个匹配:
select regexp_replace(
'Jack|Sparrow|17-09-16|DY7009|Address at some where|details',
'^([^\|]*\|){3}([^\|]*)\|.*$',
'\4'
) as col
from dual;
编辑:感谢Arijit Kanrar指出丢失的转义字符。
要OP:regex_replace不会替换数据库中的任何内容,只能返回返回的字符串。
答案 2 :(得分:0)
您可以使用此查询获取特定列(第n次出现)的值,如下所示
SELECT nth_string
FROM
(SELECT TRIM (REGEXP_SUBSTR (long_string, '[^|]+', 1, ROWNUM) ) nth_string ,
level AS lvl
FROM
(SELECT REPLACE('Jack|Sparrow|17-09-16|DY7009|Address at some where|details','||','| |') long_string
FROM DUAL
)
CONNECT BY LEVEL <= REGEXP_COUNT ( long_string, '[^|]+')
)
WHERE lvl = 4;
请注意,我在oracle中使用标准查询将分隔的字符串拆分为记录。要在第二种情况下处理分隔符之间的空白,我将用空格' '
替换它。应用TRIM()函数后,空间将转换为NULL。
您可以通过替换查询末尾nth
中的数字来获取任何lvl =
条记录。
让我知道您的反馈意见。感谢。
编辑:
似乎无法使用纯regexp_substr()
,因为无法在&#39; ||&#39;之间转换空白。到Oracle NULL
。需要中间TRIM()
,我正在添加replace
以便更轻松。将有一些模式直接匹配此方案,但无法找到它们。
以下是第4次出现的所有情景。
WITH t
AS (SELECT '|Jack|Sparrow|SQY778|17JULY17||00J1' long_string
FROM dual
UNION ALL
SELECT 'Jack|Sparrow|SQY778|17JULY17||00J1' long_string
FROM dual
UNION ALL
SELECT '||Jack|Sparrow|SQY778|17JULY17|00J1' long_string
FROM dual)
SELECT long_string,
Trim (Regexp_substr (mod_string, '\|([^|]+)', 1, 4, NULL, 1)) nth_string
FROM (SELECT long_string,
Replace(long_string, '||', '| |') mod_string
FROM t) ;
LONG_STRING NTH_STRING
------------------------ -----------
|Jack|Sparrow|SQY778|17JULY17||00J1 17JULY17
Jack|Sparrow|SQY778|17JULY17||00J1 NULL
||Jack|Sparrow|SQY778|17JULY17|00J1 SQY778
EDIT2 :最后一个模式给出了解决方案。谢谢Gary_W
要从字符串中获取nth
,请使用:
WITH t
AS (SELECT '|Jack|Sparrow|SQY778|17JULY17||00J1' long_string
FROM dual
UNION ALL
SELECT 'Jack|Sparrow|SQY778|17JULY17||00J1' long_string
FROM dual
UNION ALL
SELECT '||Jack|Sparrow|SQY778|17JULY17|00J1' long_string
FROM dual)
SELECT long_string,
Trim (regexp_substr (long_string, '(.*?)(\||$)', 1, :n + 1, NULL, 1)) nth_string
FROM t;
答案 3 :(得分:0)
没有足够的声誉来评论克里斯·约翰逊的答案,所以加上我自己的答案。 Chris有正确的方法使用反向引用但忘记逃避管道角色。 正则表达式将如下所示。
WITH dat
AS (SELECT 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details' AS str,
3 AS pos
FROM DUAL
UNION
SELECT ' |Jack|Sparrow|17-09-16||Address at some where|details' AS str,
4 AS pos
FROM DUAL)
SELECT str,
pos,
REGEXP_REPLACE (str, '^([^\|]*\|){' || pos || '}([^\|]*)\|.*$', '\2')
AS regex_result
FROM dat;
我通过动态添加管道角色的位置来动态创建正则表达式。
结果如下所示。
|杰克|麻雀| 17-09-16 ||地址在某处|详情(4):
Jack | Sparrow | 17-09-16 | DY7009 |地址在某处|详情(3):DY7009