我正在努力使用正则表达式替换解决方案,它将从VARCHAR2字段中删除引号之间的所有文本,即使这些引号之间的文本也有引号文本,例如文本:
'text start 'text inside' text end' leftover 'some other text'
正则表达式替换后应包含:leftover
我想出的代码是这样的:
with tbl as (
select
'''text start ''text inside'' text end'' leftover ''some other text''' as str
,'\''(.*?)\''' as regex
from dual
)
select
tbl.str as strA
,regexp_replace(tbl.str,tbl.regex, '') as strB
from tbl;
但是子引号之间的文本仍然存在。
是否有可能使用正则表达式来实现这一点,或者我是否应该在某个循环中拆分和分析内容?理想的解决方案是,它可以处理引用文本中出现的无限级别的引用文本。
发布于 2013-04-15 12:46:41
理想的解决方案是,如果它可以处理引用文本中出现的无限级别的引用文本。
使用单个正则表达式是不可能的。
递归正则表达式和递归捕获缓冲区在Oracle中都不可用。
更新:
但这可以通过SQL来完成:
with tbl as (
select
'''text start ''text inside'' text end'' leftover ''some other text'''
as str
from dual
)
select
listagg(text) within group (order by n)
from
(
select
n,
sum(decode(regexp_replace(str, '^(.*?([<>])){'||n||'}.*$', '\2'),
'<', 1, '>', -1, 0)) over (order by n) as nest,
regexp_replace(str, '^(.*?[<>]){'||n||'}([^<>]*).*$', '\2') as text
from
( select regexp_replace(regexp_replace(str, '(\s|^)''', '\1<'),
'''(\s|$)', '>\1') as str from tbl ),
( select level-1 as n from dual
connect by level-1 <= (select regexp_count(str, '''') from tbl) )
)
where nest = 0
发布于 2013-04-15 12:10:59
试一试
, '^[^'']*(''.*'')[^'']*$' as regex
警告:这将在捕获组1中的测试文本中捕获第一个和最后一个单引号之间的所有内容,包括最外面的引号本身。特别是,它不检查正确的嵌套。
更重要的是,您的替换expr将更加复杂:
, CASE WHEN REGEXP_INSTR(test, regex) > 0
THEN REPLACE ( test, REGEXP_REPLACE(test, regex, '\1'), '' )
ELSE test
END
如果regexp匹配,则首先提取捕获组,以便在普通替换中使用(这是可行的,因为可以保证匹配的部分是最大的)。
重要提示:该解决方案不会在您提供的特定上下文中产生所需的结果。但是,使用plsql regexp
函数再好不过了,因为oracle regex引擎没有提供扩展来表示模式中的递归(例如。pcre do)。您需要此工具来解析嵌套构造(即,执行平衡计数)。
https://stackoverflow.com/questions/16012963
复制相似问题