Sql 空字符的Oracle正则表达式
在Oracle 11g中,如何在正则表达式中检测空字符(Sql 空字符的Oracle正则表达式,sql,regex,oracle,oracle11g,Sql,Regex,Oracle,Oracle11g,在Oracle 11g中,如何在正则表达式中检测空字符(chr(0)) 我希望以下条件的评估结果为真,但事实并非如此: select case when regexp_like (chr(0), '\0') then 1 else 0 end from dual; 我的特定用例要求在varchar2列中检测空字符模式: select * from my_table where NOT regexp_like (my_column, '^[\s\0]+$'); 您可以使用字符类 SELECT
chr(0)
)
我希望以下条件的评估结果为真,但事实并非如此:
select case when regexp_like (chr(0), '\0') then 1 else 0 end from dual;
我的特定用例要求在varchar2列中检测空字符模式:
select * from my_table where NOT regexp_like (my_column, '^[\s\0]+$');
您可以使用字符类
SELECT
CASE
WHEN regexp_like (chr(0), '[[:cntrl:]]')
THEN 1
ELSE 0
END control_chr
FROM dual;
CONTROL_CHR
-----------
1
我对这个问题做了一些研究。chr(0)是一个到处都在造成混乱的东西 我首先创建了一个表,在其中插入了一个带有chr(0)的字符串,并尝试使用类似regexp_的方法来查找它
CREATE TABLE t1(col1 VARCHAR2(10));
INSERT INTO t1 VALUES('01234' || chr(0) || '5678');
SELECT CASE WHEN REGEXP_LIKE(col1,CHR(0)) THEN 1 ELSE 0 END op,col1, dump(col1) FROM t1;
产量低于-
op col1 dump(col1)
---- ----- -------------------------------------------------
1 01234 Typ=1 Len=10: 48,49,50,51,52,0,53,54,55,56
正如您所看到的,转储显示chr(0)实际上在其中,尽管在屏幕上显示字符串时,该工具将chr(0)视为空终止符,而不显示其余的。因此,似乎regexp_like实际上是在字符串中查找chr(0)的匹配项
但令我彻底失望的是,我发现即使是没有chr(0)的字符串也会返回相同的结果
DELETE FROM t1;
INSERT INTO t1 VALUES('0123456789');
SELECT CASE WHEN REGEXP_LIKE(col1,CHR(0)) THEN 1 ELSE 0 END op,col1, dump(col1) FROM t1;
op col1 dump(col1)
----- ------- ----------------------------------------------------
1 0123456789 Typ=1 Len=10: 48,49,50,51,52,53,54,55,56,57
因此,处理chr(0)有些可疑。我发布了下面的问题,并得到了同样的解释。chr(0)是一个长度为零的字符串,每当我们试图在字符串中找到它时,它显然会在任何地方找到它,实际上在任何地方都找不到它
似乎无法在字符串中找到chr(0)。请参阅MTO的回复
您可以使用
LIKE
或INSTR
和CHR(0)
来检测它,但是REGEXP\u LIKE
不起作用,因为它专门处理CHR(0)
create table t1 (col1 varchar2(10));
insert into t1 values ('01234'||chr(0)||'5678');
insert into t1 values ('01234X5678');
select case when col1 like '%'||chr(0)||'%' then 1 else 0 end r, col1, dump(col1) from t1;
select case when instr(col1,chr(0)) > 0 then 1 else 0 end r, col1, dump(col1) from t1;
上述两个查询均显示以下结果:
这将产生以下结果:
您确实需要小心,因为有些客户端在遇到
CHR(0)
时会停止读取字符串。例如,当我尝试从SQL Developer的查询结果网格复制和粘贴时,它在该点停止。似乎不可能仅识别Oracle正则表达式中的空字符。指示支持哪些正则表达式,并且未提及支持元字符或标识空字符的表达式(尽管支持其他标准元字符的子集)。我的测试已经证实了这一点,其他人在这个线程中执行了一些后续测试
虽然这个问题的答案是不可能的,但其他一些答案可能有助于满足其他人的用例。特别是,请参阅这篇文章,其中建议使用
[[:cntrl:]
类。这将识别正则表达式中的空字符,尽管它也将与类中的其他字符匹配。否,空字符(chr(0)
)与空字符串或null不同,这是完全不同的。@JeffreyKemp:我想你指的是NUL
,而不是null
?不管怎样,它们是不同的-同意的。@JeffreyKemp,其中显示了chr(0)
,\0
,0x00
与NUL
;关于NULL | NUL。我很确定混乱已经接踵而至……我强烈建议您解决真正的问题,即允许在数据中嵌入NULL字符的设计。节省自己的时间和金钱。现在就让这个项目有点意义吧,以免在未来的几年里,当不同的人需要使用不同的工具来处理和打印这些数据时,这些工具都不能处理这些空值!如果你现在就想出了一个乱七八糟的办法,那么你就是那个在将来被要求想出更多乱七八糟的办法并且永远被这段代码卡住的人!停止疯狂!:-)谢谢这对于我的用例可能已经足够了;但是,[:cntrl://code>类还包括空字符以外的其他字符,例如chr(7)
。有没有办法只检测空字符?您在什么版本的Oracle数据库上尝试过这种方法?它在11gR2上对我来说效果很好-chr(0)被认为只是另一个角色,它出现时没有问题。然而,chr(0)是由regexp_like专门处理的,这就是为什么我会使用like,它正确地处理它。“regexp_like
将不起作用,因为它专门处理chr(0)
您对此有任何参考吗?不幸的是,LIKE
和INSTR
都不适用于我的用例;我需要一个正则表达式来查找包含空字符的特定模式。@shelley-这已经在另一个答案中了。在这里参考MT0的答案:在调用REGEXP\u之前,您可以用另一个字符串替换CHR(0)
。这个问题是在我的问题之后提出的,并且也不包含对Oracle文档的任何引用。字符串操作是不安全的,因为无法保证替换的字符不会以其他方式存在于字符串中。
select case when regexp_like(col1,chr(0)) then 1 else 0 end r, col1, dump(col1) from t1;