在 Oracle 中使用正则表达式 sql
Using regex in Oracle sql
我想提取某个字符串的两部分。为此,我想使用正则表达式。
例如,字符串是:Big_Dog_0044_0080,我的正则表达式是:Big_Dog_([0-9]+)_?([0-9A-Z]*)
第 1 组将是 0044,第二组将是 0080。
现在我的问题是将其放入 select 语句中:
我用 regex_substr.
试过了
这是我的结果:
select
'Big_Dog_0044_0080' as TestString,
regexp_substr('Big_Dog_0044_0080', '([0-9]+)') Group1 ,
regexp_substr('Big_Dog_0044_0080', '([0-9A-Z]*)') Group2 from dual;
我的输出:
TESTSTRING Group1 Group2
Big_Dog_0044_0080 0044 B
首先,第 2 组是错误的,我希望是 0080。
我在这里做错了什么?
第二个问题,还有其他办法解决吗?
我想使用 5-6 个不同的正则表达式。例如下一个是
([A-C])_CatWeezle
我的意思是像 select 输入字符串列并检查可能的正则表达式。
如果一个正则表达式匹配,则停止并提取值。
谢谢!
第一部分问题很简单:
SQL> SELECT 'Big_Dog_0044_0080' AS TestString,
2 REGEXP_SUBSTR ('Big_Dog_0044_0080', '\d+', 1, 1) Group1,
3 REGEXP_SUBSTR ('Big_Dog_0044_0080', '\d+', 1, 2) Group2
4 FROM DUAL;
TESTSTRING GROU GROU
----------------- ---- ----
Big_Dog_0044_0080 0044 0080
SQL>
我不太明白你说 CatWeezle 的意思。
What I am doing wrong here?
正则表达式 '([0-9A-Z]*)'
将匹配字符串中首次出现的零个或多个数字或大写字母字符。对于您的字符串 'Big_Dog_0044_0080'
,第一个字符是大写字母字符 B
以便匹配,第二个字符 i
与您的正则表达式不匹配,因此它不包含在组。
您声明您的字符串与模式匹配:
Big_Dog_([0-9]+)_?([0-9A-Z]*)
然后您可以使用 $
将模式锚定到字符串的末尾,并且可以使用:
WITH test_data (value) AS (
SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440A80' FROM DUAL
)
SELECT value,
REGEXP_SUBSTR(value, '([0-9]+)_?([0-9A-Z]*)$', 1, 1, NULL, 1) AS Group1 ,
REGEXP_SUBSTR(value, '([0-9]+)_?([0-9A-Z]*)$', 1, 1, NULL, 2) AS Group2
FROM test_data;
输出:
VALUE
GROUP1
GROUP2
Big_Dog_0044_0080
0044
0080
Big_Dog_00440080
00440080
Big_Dog_00440A80
00440
A80
(注意:第二行完全匹配第一组,第二组宽度为零,第三行匹配第一组,直到找到非数字字符,然后开始第二组。)
如果分隔下划线是可选的,那么您可能希望使用固定宽度的匹配项(假设每个子字符串都是 4 个字符):
WITH test_data (value) AS (
SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440A80' FROM DUAL
)
SELECT value,
REGEXP_SUBSTR(value, '([0-9]{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 1) AS Group1 ,
REGEXP_SUBSTR(value, '([0-9]{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 2) AS Group2
FROM test_data;
输出:
VALUE
GROUP1
GROUP2
Big_Dog_0044_0080
0044
0080
Big_Dog_00440080
0044
0080
Big_Dog_00440A80
0044
0A80
I mean like select the input string column and go through the possible regexp. If one regexp matches, then stop and extract values.
使用CASE
表达式:
WITH test_data (value) AS (
SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440A80' FROM DUAL UNION ALL
SELECT 'A_CatWeezle' FROM DUAL
)
SELECT value,
CASE
WHEN REGEXP_LIKE(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$')
THEN REGEXP_SUBSTR(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 1)
WHEN REGEXP_LIKE(value, '^([A-C])_CatWeezle$')
THEN REGEXP_SUBSTR(value, '^([A-C])_CatWeezle$', 1, 1, NULL, 1)
END AS group1,
CASE
WHEN REGEXP_LIKE(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$')
THEN REGEXP_SUBSTR(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 2)
END AS group2
FROM test_data;
输出:
VALUE
GROUP1
GROUP2
Big_Dog_0044_0080
0044
0080
Big_Dog_00440080
0044
0080
Big_Dog_00440A80
0044
0A80
A_CatWeezle
A
db<>fiddle here
我想提取某个字符串的两部分。为此,我想使用正则表达式。 例如,字符串是:Big_Dog_0044_0080,我的正则表达式是:Big_Dog_([0-9]+)_?([0-9A-Z]*) 第 1 组将是 0044,第二组将是 0080。
现在我的问题是将其放入 select 语句中: 我用 regex_substr.
试过了这是我的结果:
select
'Big_Dog_0044_0080' as TestString,
regexp_substr('Big_Dog_0044_0080', '([0-9]+)') Group1 ,
regexp_substr('Big_Dog_0044_0080', '([0-9A-Z]*)') Group2 from dual;
我的输出:
TESTSTRING Group1 Group2
Big_Dog_0044_0080 0044 B
首先,第 2 组是错误的,我希望是 0080。 我在这里做错了什么?
第二个问题,还有其他办法解决吗? 我想使用 5-6 个不同的正则表达式。例如下一个是 ([A-C])_CatWeezle
我的意思是像 select 输入字符串列并检查可能的正则表达式。 如果一个正则表达式匹配,则停止并提取值。
谢谢!
第一部分问题很简单:
SQL> SELECT 'Big_Dog_0044_0080' AS TestString,
2 REGEXP_SUBSTR ('Big_Dog_0044_0080', '\d+', 1, 1) Group1,
3 REGEXP_SUBSTR ('Big_Dog_0044_0080', '\d+', 1, 2) Group2
4 FROM DUAL;
TESTSTRING GROU GROU
----------------- ---- ----
Big_Dog_0044_0080 0044 0080
SQL>
我不太明白你说 CatWeezle 的意思。
What I am doing wrong here?
正则表达式 '([0-9A-Z]*)'
将匹配字符串中首次出现的零个或多个数字或大写字母字符。对于您的字符串 'Big_Dog_0044_0080'
,第一个字符是大写字母字符 B
以便匹配,第二个字符 i
与您的正则表达式不匹配,因此它不包含在组。
您声明您的字符串与模式匹配:
Big_Dog_([0-9]+)_?([0-9A-Z]*)
然后您可以使用 $
将模式锚定到字符串的末尾,并且可以使用:
WITH test_data (value) AS (
SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440A80' FROM DUAL
)
SELECT value,
REGEXP_SUBSTR(value, '([0-9]+)_?([0-9A-Z]*)$', 1, 1, NULL, 1) AS Group1 ,
REGEXP_SUBSTR(value, '([0-9]+)_?([0-9A-Z]*)$', 1, 1, NULL, 2) AS Group2
FROM test_data;
输出:
VALUE GROUP1 GROUP2 Big_Dog_0044_0080 0044 0080 Big_Dog_00440080 00440080 Big_Dog_00440A80 00440 A80
(注意:第二行完全匹配第一组,第二组宽度为零,第三行匹配第一组,直到找到非数字字符,然后开始第二组。)
如果分隔下划线是可选的,那么您可能希望使用固定宽度的匹配项(假设每个子字符串都是 4 个字符):
WITH test_data (value) AS (
SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440A80' FROM DUAL
)
SELECT value,
REGEXP_SUBSTR(value, '([0-9]{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 1) AS Group1 ,
REGEXP_SUBSTR(value, '([0-9]{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 2) AS Group2
FROM test_data;
输出:
VALUE GROUP1 GROUP2 Big_Dog_0044_0080 0044 0080 Big_Dog_00440080 0044 0080 Big_Dog_00440A80 0044 0A80
I mean like select the input string column and go through the possible regexp. If one regexp matches, then stop and extract values.
使用CASE
表达式:
WITH test_data (value) AS (
SELECT 'Big_Dog_0044_0080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440080' FROM DUAL UNION ALL
SELECT 'Big_Dog_00440A80' FROM DUAL UNION ALL
SELECT 'A_CatWeezle' FROM DUAL
)
SELECT value,
CASE
WHEN REGEXP_LIKE(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$')
THEN REGEXP_SUBSTR(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 1)
WHEN REGEXP_LIKE(value, '^([A-C])_CatWeezle$')
THEN REGEXP_SUBSTR(value, '^([A-C])_CatWeezle$', 1, 1, NULL, 1)
END AS group1,
CASE
WHEN REGEXP_LIKE(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$')
THEN REGEXP_SUBSTR(value, '^Big_Dog_(\d{4})_?([0-9A-Z]{4})$', 1, 1, NULL, 2)
END AS group2
FROM test_data;
输出:
VALUE GROUP1 GROUP2 Big_Dog_0044_0080 0044 0080 Big_Dog_00440080 0044 0080 Big_Dog_00440A80 0044 0A80 A_CatWeezle A
db<>fiddle here