[英]Oracle sql regular expression
我在表中的列中有一個像這樣的字符串'abc : efg : xyz'
,該列的所有記錄都將是這樣。 我想要最后一個冒號(:)之后的該字符串的子字符串。 請確實需要幫助
例:
'abc : efg : xyz' -> xyz </br>
'abc : efg : efghj'-> efghj
我對此有以下查詢,但我想短於此查詢:
SELECT REPLACE (
REGEXP_SUBSTR (
'abc : efg : xyz',
':.*$',
REGEXP_INSTR (
'abc : efg : xyz',
':',
1,
LENGTH ('abc : efg : xyz')
- LENGTH (
REPLACE ('abc : efg : xyz',
':',
NULL))),
1),
': ') data_after_the_last_colon
FROM DUAL
正如您所說的那樣,模式是固定的,反轉字符串並尋找並獲得子字符串,直到最簡單的第一個分號為止。 您還可以使用trim
來消除任何前導/尾隨空格。
select reverse(substr(reverse('abc : efg : efghj'),
1,instr(reverse('abc : efg : efghj'),':')-1)) from dual
如果INSTR函數的位置參數為負,它將從字符串的末尾開始倒數。 因此,您可以使用如下所示的內容:
SELECT TRIM(SUBSTR('abc : efg : efghj',INSTR('abc : efg : efghj',':',-1) + 1))
FROM dual;
您想要的是:
REGEXP_REPLACE (INPUTSTR, '^([^:]+ : )*', '')
具體來說,這將查找從開頭(初始插入符號^
)開始的,出現零次或多次出現且帶有非分號( [^:]+
)后跟:
的字符串的字符串。 它用空字符串替換所有以空格,冒號終止的前導字符串。
以下查詢演示了它是如何工作的。 我在樣本輸入和其他六個測試中使用了分解式子查詢,並且查詢輸出具有輸入,我的regexp_replace結果和您的REPLACE (REGEXP_SUBSTR
語法(我用分解式替換了您的' abc : efg : xyz '
您可以通過復制並union all select
行並更改inputstr
的字符串來添加另一個測試用例。
哦,關於doold
-您的語法無法在沒有冒號的情況下處理輸入字符串,這將引發錯誤,導致所有查詢結果被殺死。 因此,我將您的語法包裝在DECODE (doold
將所有行都取回DECODE (doold
。
with sampl as (
select 'abc : efg : xyz' as inputstr, 1 as doold from dual
union all select 'z : b :' as inputstr, 1 as doold from dual
union all select 'z : b : ' as inputstr, 1 as doold from dual
union all select ' : a ' as inputstr, 1 as doold from dual
union all select ' a ' as inputstr, 0 as doold from dual
union all select '' as inputstr, 1 as doold from dual
union all select ' hij : klm : nop : qrs : tuv' as inputstr, 1 as doold from dual
)
SELECT
inputstr,
regexp_replace (inputstr, '^([^:]+ : )*', '') as bettr,
decode (doold,
1, -- the following is your original expression, for comparison
-- purposes, edited only to replace 'abc : efg : xyz' with inputstr
REPLACE (
REGEXP_SUBSTR (
inputstr,
':.*$',
REGEXP_INSTR (
inputstr,
':',
1,
LENGTH (inputstr)
- LENGTH (
REPLACE (inputstr,
':',
NULL))),
1),
': '),
'Sorry the syntax won''t support input "' || inputstr || '"'
) data_after_the_last_colon
FROM sampl
order by doold desc, length (inputstr)
干得好。 這也適用於NULL列表元素:
SQL> with tbl(row_nbr, str) as (
2 select 1, 'abc : efg : xyz' from dual
3 union
4 select 2, 'abc : efg : efghj' from dual
5 union
6 select 3, 'abc : : efghj' from dual
7 )
8 select row_nbr, regexp_substr(str, '(.*?)( : |$)', 1, regexp_count(str, ' \: ')+1, null, 1)
9 from tbl
10 order by row_nbr;
ROW_NBR REGEXP_SUBSTR(STR
---------- -----------------
1 xyz
2 efghj
3 efghj
SQL>
如果要解析整個列表:
SQL> with tbl(row_nbr, str) as (
2 select 1, 'abc : efg : xyz' from dual
3 union
4 select 2, 'abc : efg : efghj' from dual
5 union
6 select 3, 'abc : : efghj' from dual
7 )
8 SELECT row_nbr, str,
9 COLUMN_VALUE AS match_nbr,
10 REGEXP_SUBSTR( str ,'(.*?)( : |$)', 1, COLUMN_VALUE, NULL, 1 ) AS match_value
11 FROM tbl,
12 TABLE(
13 CAST(
14 MULTISET(
15 SELECT LEVEL
16 FROM DUAL
17 CONNECT BY LEVEL <= REGEXP_COUNT( str ,' : ' )+1
18 ) AS SYS.ODCINUMBERLIST
19 )
20 );
ROW_NBR STR MATCH_NBR MATCH_VALUE
---------- ----------------- ---------- -----------------
1 abc : efg : xyz 1 abc
1 abc : efg : xyz 2 efg
1 abc : efg : xyz 3 xyz
2 abc : efg : efghj 1 abc
2 abc : efg : efghj 2 efg
2 abc : efg : efghj 3 efghj
3 abc : : efghj 1 abc
3 abc : : efghj 2
3 abc : : efghj 3 efghj
9 rows selected.
SQL>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.