Oracle ltrim的意外行为
预期结果是Oracle ltrim的意外行为,oracle,trim,texttrimming,Oracle,Trim,Texttrimming,预期结果是AOD,但当我通过更改第一个字符串运行时,会得到意外的行为。 下面是我通过改变后面的字符尝试运行的轨迹,比如BOD、COD…ZOD,下面是奇怪的结果 select ltrim('PREPROCESSINGLIST_AOD', 'PREPROCESSINGLIST_') as node_code from dual; 而且。。。我的问题是为什么会有这种奇怪的行为?这不是奇怪的行为。它是记录在案的行为 根据: LTRIM从字符的左端删除集合中包含的所有字符 因此,第二个参数虽然是字符串类
AOD
,但当我通过更改第一个字符串运行时,会得到意外的行为。
下面是我通过改变后面的字符尝试运行的轨迹,比如BOD、COD…ZOD
,下面是奇怪的结果
select ltrim('PREPROCESSINGLIST_AOD', 'PREPROCESSINGLIST_') as node_code from dual;
而且。。。我的问题是为什么会有这种奇怪的行为?这不是奇怪的行为。它是记录在案的行为
根据:
LTRIM
从字符的左端删除集合中包含的所有字符
因此,第二个参数虽然是字符串类型,但它本身不是字符串,而是一组要修剪掉的字符
因此:
When AOD Result==> AOD
When BOD Result==> BOD
When COD Result==> D
When EOD Result==> D
When FOD Result==> FOD
When GOD Result==> D
When HOD Result==> HOD
When IOD Result==> D
When JOD Result==> JOD
When KOD Result==> KOD
When LOD Result==> D
When MOD Result==> MOD
When NOD Result==> D
When OOD Result==> D
When POD Result==> D
When QOD Result==> QOD
When ROD Result==> D
When SOD Result==> D
When TOD Result==> D
When UOD Result==> UOD
When VOD Result==> VOD
When WOD Result==> WOD
When XOD Result==> XOD
When YOD Result==> YOD
When ZOD Result==> ZOD
将返回D
,因为C
和O
都在预处理列表中:
ltrim('PREPROCESSINGLIST_COD', 'PREPROCESSINGLIST_')
\u AOD
,但是,A
不在集合中,因此修剪停止在那里
如果您进行测试,您可以看到您从以下方面获得完全相同的行为:
PREPROCESSINGLIST_
^^
here
这应该与预处理列表中的字符相同
Lasse Vågsæther Karlsen已经回答了代码为何会以这种方式运行的问题。要实现所需,可以使用正则表达式:
ltrim('PREPROCESSINGLIST_COD', 'CEGILNOPRST_')
这将从字符串中删除一个前导<代码>预处理列表< /代码>,但如果它位于字符串的中间(因为<代码> ^ /代码>锚开始字符串),请将其留在那里。
如果我只想在_之后使用子字符串,那么最好使用什么
不太清楚您是否只想删除确切的字符串'PREPROCESSINGLIST.
,如果是这样,是否应该只在字符串的开头或任何地方进行匹配;或者您希望删除第一个下划线以下的内容,或者删除任何下划线以下的内容
根据您的实际数据和想要得到的结果,您可以使用@Franksmitt显示的regexp\u replace()
(带或不带锚点),或普通的replace()
,或instr()
和substr()
的组合
CTE中提供了一些具有各种模式的虚构数据:
select regexp_replace('PREPROCESSINGLIST_COD',
'^PREPROCESSINGLIST_',
'') as node_code
from dual;
如果可以通过多种方式获得所需的结果,那么通常避免使用正则表达式会更有效,但有时它们是唯一(明智的)选择。和往常一样,最好根据实际数据自己测试选项,看看什么是最有效的,或者至少是足够有效的。你可以复制我答案的所有内容,我可以删除我的内容,在这里,我认为更重要的是告诉他如何获得他想要的行为,而不是仅仅解释他当前代码不起作用的原因。@LasseVågsætherKarlsen我认为首先解释原始代码不起作用的原因很重要,所以我更希望我们保留这两个答案(这不完全是利他主义-我还是希望有一天能获得体育精神徽章:-)@FrankSchmitt,谢谢,我害怕使用regexp\u replace
,因为如果在使用它的过程中出现性能问题的话。因此,我发现<代码>替换< /代码>子句也将做同样的工作,请建议选择哪一个。@ SuryAPRAKASBISAY——基本<代码>替换<代码>将在字符串的中间匹配;正如Frank提到的,正则表达式模式中的锚定表示只在开始时匹配。所以,你使用哪一个部分取决于这是否重要。您也可以使用instr
/substr
,但这并没有那么简单(但可能更快)。谢谢,如果我只想在\uu
之后使用子字符串,那么最好使用什么?我知道@Frank提到的使用regexp\u replace
的答案,但是使用regexp\u replace
的效率有多高我没有发表关于regex\u replace的文章的原因是我根本不是Oracle专家,我只是根据在其他系统中使用类似功能的经验知道问题可能出在哪里,并且阅读文档后告诉我问题出在哪里,但是如果我在湿纸袋中,我无法编写一种有效的方法来完成您想要的任务。好吧,结果是错的,但我想说的是,你应该问一下:)
with t (str) as (
select 'PREPROCESSINGLIST_AOD' from dual
union all select 'PREPROCESSINGLIST_BOD' from dual
union all select 'PREPROCESSINGLIST_COD' from dual
union all select 'PREPROCESSINGLIST_DOD' from dual
union all select 'XYZ_PREPROCESSINGLIST_EOD' from dual
union all select 'XYZ_FOD' from dual
union all select 'ABC_XYZ_GOD' from dual
union all select 'HOD' from dual
)
select str,
regexp_replace(str, '^PREPROCESSINGLIST_', null) as anchor_regex,
regexp_replace(str, 'PREPROCESSINGLIST_', null) as free_regex,
replace(str, 'PREPROCESSINGLIST_', null) as free_replace,
case when instr(str, '_') > 0 then substr(str, instr(str, '_') + 1) else str end
as first_underscore,
case when instr(str, '_') > 0 then substr(str, instr(str, '_', -1) + 1) else str end
as last_underscore
from t;
STR ANCHOR_REGEX FREE_REGEX FREE_REPLAC FIRST_UNDERSCORE LAST_UNDERS
------------------------- ------------------------- ----------- ----------- --------------------- -----------
PREPROCESSINGLIST_AOD AOD AOD AOD AOD AOD
PREPROCESSINGLIST_BOD BOD BOD BOD BOD BOD
PREPROCESSINGLIST_COD COD COD COD COD COD
PREPROCESSINGLIST_DOD DOD DOD DOD DOD DOD
XYZ_PREPROCESSINGLIST_EOD XYZ_PREPROCESSINGLIST_EOD XYZ_EOD XYZ_EOD PREPROCESSINGLIST_EOD EOD
XYZ_FOD XYZ_FOD XYZ_FOD XYZ_FOD FOD FOD
ABC_XYZ_GOD ABC_XYZ_GOD ABC_XYZ_GOD ABC_XYZ_GOD XYZ_GOD GOD
HOD HOD HOD HOD HOD HOD