SQL Fiddle
查詢1:
這是如何使用正則表達式替換做到這一點:
(和一些邊緣的情況下再次進行測試 - NULL
姓氏,後綴加上姓氏和雙管姓)
WITH strings AS (
SELECT 'Name1 Surname1 (AB123), Name2 Surname2 (MN456), Name3 Surname3(xy789)' AS str FROM DUAL
UNION ALL SELECT 'Madonna (MA001), John Jones(Jr) (JJ001), Doctor Doctor(PhD) (dd001), Alf Double-Barrelled (AD001)' AS str FROM DUAL
)
SELECT REGEXP_REPLACE(str, '.*?\(([[:alpha:]]{2}[[:digit:]]{3})\)\s*(,|$)', '\1\2') AS match
FROM strings
Results:
| MATCH |
|-------------------------|
| AB123,MN456,xy789 |
| MA001,JJ001,dd001,AD001 |
查詢2:
這是如何使用分層查詢做到這一點:
WITH str AS (
SELECT 'Name1 Surname1 (AB123), Name2 Surname2 (MN456), Name3 Surname3(xy789)' AS str
FROM DUAL
),
lengths AS (
SELECT str,
REGEXP_COUNT(str, '\(([[:alpha:]]{2}[[:digit:]]{3})\)\s*(,|$)') AS len
FROM str
)
SELECT SUBSTR(
SYS_CONNECT_BY_PATH (
REGEXP_SUBSTR (
str,
'\(([[:alpha:]]{2}[[:digit:]]{3})\)\s*(,|$)',
1,
LEVEL,
NULL,
1
),
','
),
2
) AS match
FROM lengths
WHERE LEVEL = len
CONNECT BY LEVEL <= len
Results:
| MATCH |
|-------------------|
| AB123,MN456,xy789 |
查詢3:
如果您正在使用版本的Oracle,其中預日期REGEXP_COUNT
那麼你可以使用的LENGTH
並在其位置REGEXP_REPLACE
的組合;像這樣:
WITH str AS (
SELECT 'Name1 Surname1 (AB123), Name2 Surname2 (MN456), Name3 Surname3(xy789)' AS str
FROM DUAL
)
SELECT str,
REGEXP_COUNT(str, '\(([[:alpha:]]{2}[[:digit:]]{3})\)\s*(,|$)') AS len,
LENGTH(REGEXP_REPLACE(str, '.*?\(([[:alpha:]]{2}[[:digit:]]{3})\)\s*(,|$)', 'X')) AS len2
FROM str
Results:
| STR | LEN | LEN2 |
|-----------------------------------------------------------------------|-----|------|
| Name1 Surname1 (AB123), Name2 Surname2 (MN456), Name3 Surname3(xy789) | 3 | 3 |
嘿,西蒙你能否請解釋上面的答案,因爲我是REGEX的新手。從第一眼看來,似乎你將從Name1 Surname1(AB123)替換除AB123以外的所有東西。 – jaychapani
是的,沒錯! '[^ \(] +?\('表示所有內容直到「(」,'([[:alpha:] {2} [[:digit:]] {3} 「用作\ 2和'\)'是當前塊的結尾(在這種情況下你有3個) – smnbbrv
,不需要使用outer():可以刪除,並且\ 2應該被改變然後到\ 1.更新答案 – smnbbrv