select ltrim('PREPROCESSINGLIST_AOD', 'PREPROCESSINGLIST_') as node_code from dual;
预期结果是AOD
,但是当我通过更改第一个字符串来运行时会出现意外行为。
下面是我尝试通过更改_
之类的字符(例如BOD, COD...ZOD
)而尝试并运行的线索,下面是奇怪的结果。
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
然后...我的问题为什么是这种奇怪的行为?
答案 0 :(得分:4)
这不是奇怪的行为。这是已记录的行为。
LTRIM
从 char 的左端删除 set 中包含的所有字符。
因此,第二个参数尽管是字符串 type ,但不是 string ,而是要修剪的一组字符。
所以这个:
ltrim('PREPROCESSINGLIST_COD', 'PREPROCESSINGLIST_')
由于D
和C
都在O
中,因此最终将返回PREPROCESSINGLIST_
:
PREPROCESSINGLIST_
^^
here
_AOD
,但是A
未在集合中,因此修剪在此处停止。
如果进行测试,您会发现您得到的行为完全相同:
ltrim('PREPROCESSINGLIST_COD', 'CEGILNOPRST_')
该字符应与PREPROCESSINGLIST_
中的字符相同。
答案 1 :(得分:3)
LasseVågsætherKarlsen已经回答了为什么您的代码如此操作的问题。要实现所需的功能,可以使用正则表达式:
select regexp_replace('PREPROCESSINGLIST_COD',
'^PREPROCESSINGLIST_',
'') as node_code
from dual;
这将从字符串中删除前导PREPROCESSINGLIST
,但是如果它位于字符串的中间,则将其保留在该字符串中(因为^
锚定为字符串的开头)。
答案 2 :(得分:3)
如果我只想要_后面的子字符串,最好使用什么?
目前尚不清楚是否只删除确切的字符串'PREPROCESSINGLIST_'
,如果要删除,则仅在字符串的开头或任何位置进行匹配;或者您要删除直到第一个下划线的所有内容,或删除至任何下划线的所有内容。
根据您的实际数据和想要获得的结果,可以使用regexp_replace()
,如@FrankScmitt显示的那样(带有或不带有锚点),也可以使用普通的replace()
或{ {1}}和instr()
。
在CTE中提供了一些带有各种模式的虚构数据:
substr()
如果可以多种方式获得所需的结果,则避免正则表达式通常更为有效,但有时它们是唯一(明智的选择)。与往常一样,最好根据实际数据自己测试这些选项,以查看哪种方法最有效-或至少足够有效。