我想在oracle数据库中使用REGEXP_INSTR()
来检查小写/大写字符。我知道[:upper:]
和[:lower:]
POSIX字符类,但是我选择了a-z
,这给了我我不明白的结果。有人可以解释吗?
SELECT REGEXP_INSTR('abc','[A-Z]',1,1,0,'c') FROM DUAL
-- Got 2, expected 0
SELECT REGEXP_INSTR('zyx','[A-Z]',1,1,0,'c') FROM DUAL
-- Got 1, expected 0
SELECT REGEXP_INSTR('ABC','[a-z]',1,1,0,'c') FROM DUAL
-- Got 1, expected 0
SELECT REGEXP_INSTR('ZYX','[a-z]',1,1,0,'c') FROM DUAL
-- Got 2, expected 0
SELECT REGEXP_INSTR('a3','[A-F0-9]',1,1,0,'c') FROM DUAL
-- Got 2, expected 2
SELECT REGEXP_INSTR('b3','[A-F0-9]',1,1,0,'c') FROM DUAL
-- Got 1, expected 2
SELECT REGEXP_INSTR('b3','[A-F0-9]') FROM DUAL
-- Got 1, expected 1 or 2
SELECT REGEXP_INSTR('a3','[A-F0-9]') FROM DUAL
-- Got 2, expected same as above
答案 0 :(得分:1)
该行为的原因是排序规则。参见NLS_SORT
documentation:
- 如果该值为BINARY,则ORDER BY查询的整理顺序基于字符的数字值(需要较少系统开销的二进制排序)。
- 如果该值是命名的语言排序,则排序基于定义的语言排序的顺序。 NLS_LANGUAGE参数支持的大多数(但不是全部)语言也支持同名的语言排序。
将NLS_SORT
设置为BINARY
,以便可以按与ASCII表相同的顺序来解析[A-Z]
alter session set nls_sort = 'BINARY'
然后,您将获得一致的结果。
请参见online demo。
答案 1 :(得分:-1)
好的,NLS_SORT
导致此行为的答案是正确的,但我认为它不能以一种可以理解的方式对其进行解释。我发现的任何文档都没有做到这一点……
您必须想象[a-z]
定义的字符范围实际上是由所有可能的字符的单个子字符串派生的,这些子字符串根据NLS_SORT
进行了排序。
让我们假设整个字母只是字母数字字符。按BINARY
排序,这会产生类似于0123456789abcdefgh...xyzABCDE...XYZ
的基本字符串。
因此,[0-6]
扩展到[0123456]
,[a-f]
扩展到[abcdef]
,[5-b]
扩展到[56789ab]
等。
由linguistic_definition
排序,但是会产生不同的基本字符串,例如0123456789aAbBcCdDeF...xXyYzZ
。
因此,[0-6]
仍扩展为[0123456]
,但是[a-f]
现在扩展为[aAbBcCdDeEf]
,[5-b]
扩展为[56789aAb]
等... >
这就是a
与[A-Z]
不匹配但b
相匹配的原因。 [A-Z]
实际上扩展为[AbBcC...yYzZ]
,其中包括z
但不包括a
。
实际上,[A-Z]
甚至可能包含更多字符,例如[aAàáâÀÁÂ...]
等。