Regex Oracle SQL:提取每行中所有匹配的字符串
假设我有一个带有两列ITEM和CONTENT的表MESSAGE 目前,我想用这个模式${variable}显示每个单词。预期的最终结果是Regex Oracle SQL:提取每行中所有匹配的字符串,regex,oracle,oracle12c,Regex,Oracle,Oracle12c,假设我有一个带有两列ITEM和CONTENT的表MESSAGE 目前,我想用这个模式${variable}显示每个单词。预期的最终结果是 ITEM1 | ${username}, ${address} ITEM2 | ${username} 要实现这一点,正确的Oracle SQL查询是什么?我尝试过类似的东西,但它只是列出了与匹配的正则表达式的内容 SELECT ITEM, REGEXP_SUBSTR(CONTENT, '^.*\$\{.*\}.*$', 1, 1) FROM MESSAGE
ITEM1 | ${username}, ${address}
ITEM2 | ${username}
要实现这一点,正确的Oracle SQL查询是什么?我尝试过类似的东西,但它只是列出了与匹配的正则表达式的内容
SELECT ITEM, REGEXP_SUBSTR(CONTENT, '^.*\$\{.*\}.*$', 1, 1) FROM MESSAGE;
我不太擅长正则表达式,看看这是否有帮助:
SQL> with message (item, content) as
2 (select 'ITEM1', 'Dear ${username}, you have changed your address to ${address}' from dual union
3 select 'ITEM2', 'Hi ${username}, thank you for attending this event.' from dual
4 )
5 select item,
6 regexp_substr(content, '\$\{\w+}', 1, 1) the_first,
7 regexp_substr(content, '\$\{\w+}', 1, 2) the_second
8 from message;
ITEM THE_FIRST THE_SECOND
----- -------------------- --------------------
ITEM1 ${username} ${address}
ITEM2 ${username}
SQL>
它有什么作用
\$在这里用于转义美元符号,因为它用作字符串结尾的锚点,所以-转义它
\{也一样,因为花括号表示出现的次数,所以-避开它
\w+代表整个世界
1,1和1,2:从第一个字符开始,取该表达式的第一个1,1或第二个1,2外观
将这两个表达式连接起来并用逗号分隔它们是很简单的。我不太擅长正则表达式,看看这是否有帮助:
SQL> with message (item, content) as
2 (select 'ITEM1', 'Dear ${username}, you have changed your address to ${address}' from dual union
3 select 'ITEM2', 'Hi ${username}, thank you for attending this event.' from dual
4 )
5 select item,
6 regexp_substr(content, '\$\{\w+}', 1, 1) the_first,
7 regexp_substr(content, '\$\{\w+}', 1, 2) the_second
8 from message;
ITEM THE_FIRST THE_SECOND
----- -------------------- --------------------
ITEM1 ${username} ${address}
ITEM2 ${username}
SQL>
它有什么作用
\$在这里用于转义美元符号,因为它用作字符串结尾的锚点,所以-转义它
\{也一样,因为花括号表示出现的次数,所以-避开它
\w+代表整个世界
1,1和1,2:从第一个字符开始,取该表达式的第一个1,1或第二个1,2外观
连接这两个字符并用逗号分隔它们是很简单的。您可以使用\$\{.+?\}-使用?使之成为{}之间一个或多个字符的非贪婪匹配
捕获该组
使用具有Previor的connect by循环和具有level的SYS_GUID来提取一行中所有可能的匹配项
LISTAGG进行连接
WITH message AS (
SELECT
'ITEM1' AS item,
'Dear ${username}, you have changed your address to ${address}' AS content
FROM
dual
UNION ALL
SELECT
'ITEM2',
'Hi ${username}, thank you for attending this event.'
FROM
dual
)
SELECT item,LISTAGG(content,',') WITHIN GROUP ( ORDER BY lvl )
FROM
(
SELECT
item,
regexp_substr(content,'(\$\{.+?\})',1,level,NULL,1) as content,
level as lvl
FROM
message
CONNECT BY level <= regexp_count(content,'\$\{.+?\}')
AND PRIOR item = item
AND PRIOR sys_guid() IS NOT NULL
) GROUP BY item;
您可以使用\$\{.+?\}-使用?使之成为{}之间一个或多个字符的非贪婪匹配
捕获该组
使用具有Previor的connect by循环和具有level的SYS_GUID来提取一行中所有可能的匹配项
LISTAGG进行连接
WITH message AS (
SELECT
'ITEM1' AS item,
'Dear ${username}, you have changed your address to ${address}' AS content
FROM
dual
UNION ALL
SELECT
'ITEM2',
'Hi ${username}, thank you for attending this event.'
FROM
dual
)
SELECT item,LISTAGG(content,',') WITHIN GROUP ( ORDER BY lvl )
FROM
(
SELECT
item,
regexp_substr(content,'(\$\{.+?\})',1,level,NULL,1) as content,
level as lvl
FROM
message
CONNECT BY level <= regexp_count(content,'\$\{.+?\}')
AND PRIOR item = item
AND PRIOR sys_guid() IS NOT NULL
) GROUP BY item;
这假设每个内容最多有两个变量。OP的问题不清楚该假设是否有效。这假设每个内容最多有两个变量。OP的问题不清楚该假设是否有效。