我的REGEXP表达式有问题,我想循环,每次迭代都会删除斜杠后的文本。我的表情现在看起来像这样
REGEXP_SUBSTR('L1161148/1/10', '.*(/)')
我得到L1161148 / 1 /而不是L1161148 / 1
答案 0 :(得分:1)
您可以尝试在最后一个斜杠后删除字符串:
echo "compile" > lf.txt
cp lf.txt crlf.txt
unix2dos crlf.txt
答案 1 :(得分:1)
你正试图走到最后一个/然后"回顾"并保留之前的内容。使用正则表达式,您可以使用子表达式执行此操作,如下所示:
select regexp_substr('L1161148/1/10', '(.*)/.*', 1, 1, null, 1) from dual;
在这里,像往常一样,第一个参数" 1"意味着从哪里开始搜索,第二个" 1"意味着选择匹配的子字符串," null"意味着没有特殊的匹配修饰符(如不区分大小写的匹配等 - 这里不需要),以及最后的" 1"表示返回第一个子表达式 - "匹配模式中括号中的第一个内容。"
但是,只有在不能使用标准substr和instr(和translate)函数的情况下才能使用正则表达式。这里的工作很简单:
instr(text_string, '/', -1)
将为您提供LAST / in text_string的位置(-1表示查找最后一次出现,而不是第一次出现:从字符串末尾开始计数)。所以整个事情可以写成:
select substr('L1161148/1/10', 1, instr('L1161148/1/10', '/', -1) - 1) from dual;
编辑:根据Gary_W的解决方案,这里是对几个字符串的概括,并从每个输入字符串中删除连续的图层;仍然没有使用正则表达式(导致性能略快)并使用自Oracle版本11以来可用的递归CTE;我相信Gary的解决方案仅适用于Oracle 12c。
查询:(我改变了Gary的第二个输入字符串,以确保查询正常工作)
with tbl(item_id, input_str) as (
select 1, 'L1161148/1/10/2/34/5/6' from dual union all
select 2, 'ALKD/FJV11/61148/123/456/789/1/2/3' from dual
),
r (item_id, proc_string, stage) as (
select item_id, input_str, 0 from tbl
union all
select item_id, substr(proc_string, 1, instr(proc_string, '/', -1) - 1), stage + 1
from r
where instr(proc_string, '/') > 0
)
select * from r
order by item_id, stage;
输出:
ITEM_ID PROC_STRING STAGE
---------- ---------------------------------------- ----------
1 L1161148/1/10/2/34/5/6 0
1 L1161148/1/10/2/34/5 1
1 L1161148/1/10/2/34 2
1 L1161148/1/10/2 3
1 L1161148/1/10 4
1 L1161148/1 5
1 L1161148 6
2 ALKD/FJV11/61148/123/456/789/1/2/3 0
2 ALKD/FJV11/61148/123/456/789/1/2 1
2 ALKD/FJV11/61148/123/456/789/1 2
2 ALKD/FJV11/61148/123/456/789 3
2 ALKD/FJV11/61148/123/456 4
2 ALKD/FJV11/61148/123 5
2 ALKD/FJV11/61148 6
2 ALKD/FJV11 7
2 ALKD 8
答案 2 :(得分:1)
你说你想循环。
CAVEAT:这两个解决方案都假设没有NULL列表元素(所有斜杠之间都有值)。
SQL> with tbl(data) as (
select 'L1161148/1/10' from dual
)
select level, nvl(substr(data, 1, instr(data, '/', 1, level)-1), data) formatted
from tbl
connect by level <= regexp_count(data, '/') + 1 -- Loop # of delimiters +1 times
order by level desc;
LEVEL FORMATTED
---------- -------------
3 L1161148/1/10
2 L1161148/1
1 L1161148
SQL>
编辑:处理多行:
SQL> with tbl(rownbr, col1) as (
select 1, 'L1161148/1/10/2/34/5/6' from dual
union
select 2, 'ALKDFJV1161148/123/456/789/1/2/3' from dual
)
SELECT rownbr, column_value substring_nbr,
nvl(substr(col1, 1, instr(col1, '/', 1, column_value)-1), col1) formatted
FROM tbl,
TABLE(
CAST(
MULTISET(SELECT LEVEL
FROM dual
CONNECT BY LEVEL <= REGEXP_COUNT(col1, '/')+1
) AS sys.OdciNumberList
)
)
order by rownbr, substring_nbr desc
;
ROWNBR SUBSTRING_NBR FORMATTED
---------- ------------- --------------------------------
1 7 L1161148/1/10/2/34/5/6
1 6 L1161148/1/10/2/34/5
1 5 L1161148/1/10/2/34
1 4 L1161148/1/10/2
1 3 L1161148/1/10
1 2 L1161148/1
1 1 L1161148
2 7 ALKDFJV1161148/123/456/789/1/2/3
2 6 ALKDFJV1161148/123/456/789/1/2
2 5 ALKDFJV1161148/123/456/789/1
2 4 ALKDFJV1161148/123/456/789
2 3 ALKDFJV1161148/123/456
2 2 ALKDFJV1161148/123
2 1 ALKDFJV1161148
14 rows selected.
SQL>