使用类似oracle REGEXP_的函数查找具有相同数字(包括破折号)的SSN

使用类似oracle REGEXP_的函数查找具有相同数字(包括破折号)的SSN,regex,oracle,Regex,Oracle,我试图用破折号(-)过滤掉具有相同数字的SSN。这意味着SSN中的所有数字都是相同的,并且遵循xxx xx xxxx格式 示例: 更正过滤值:111-11-1111000-00-0000 错误的筛选值:123-45-6789012-34-5678 数据在Oracle数据库中,所以我使用类似REGEXP_的函数,下面是我的sql SELECT id FROM table WHERE id_typ='SSN' AND REGEXP_LIKE(id,'^([0-9])(?=\1{2}-\1{2}-\

我试图用破折号(-)过滤掉具有相同数字的SSN。这意味着SSN中的所有数字都是相同的,并且遵循xxx xx xxxx格式

示例:

更正过滤值:111-11-1111000-00-0000

错误的筛选值:123-45-6789012-34-5678

数据在Oracle数据库中,所以我使用类似REGEXP_的函数,下面是我的sql

SELECT id FROM table
WHERE id_typ='SSN' 
AND REGEXP_LIKE(id,'^([0-9])(?=\1{2}-\1{2}-\1{4})[0-9]{2}-[0-9]{2}-[0-9]{4}$');
您可以在以下位置测试正则表达式:

上面的查询没有返回任何数据

如果我用^[0-9]{3}-[0-9]{2}-[0-9]{4}$替换上述正则表达式,它将返回我的数据,但具有不同的数字ssn,这是正确的行为,但是错误的要求

那么我遗漏了什么呢?

这里有一个有趣(但正确!)的方法来检查社保号码中的“所有数字都是相等的”。假设:假设输入字符串的长度正好为11,第四个和第七个字符为破折号(
-
),其余为数字

with
  inputs ( ssn ) as (
    select '123-00-4020' from dual union all
    select '333-33-3333' from dual union all
    select '013-35-4444' from dual
  )
-- End of simulated inputs. Query begins BELOW THIS LINE.
select ssn
from   inputs
where  mod(to_number(ssn, '999G99G9999', 'nls_numeric_characters='',-'''), 111111111) = 0
;

SSN
-----------
333-33-3333
说明:我将
ssn
解释为一个数字,用“千”分隔符书写,我声明它是破折号,而不是逗号(在英语国家)或点(在世界大多数其他国家)。我在NLS\u NUMERIC\u CHARACTERS参数中这样做:我声明
为十进制分隔符,
-
为“组”分隔符。Oracle允许“组”分隔符出现在任何地方——正是因为这个原因,它被称为“组”,而不是“千”分隔符。在某些文化中,群体不一定是数千人;例如,印度常用的1亿表示法是
10,00,00000
——Oracle也适用于此。通过这样做,它也适应了我的黑客行为——在方便的时候使用“组分隔符”,尽管这不是我想要的意思

其余的都是琐碎的;当且仅当九位数可被111111整除时,九位数具有所有相等的位数

如果要ex包含这些字符串,请将
=
更改为
=

代码


解释
  • ^
    在行首断言位置
  • (\d)
    将任何数字捕获到捕获组1中
  • \1{2}
    与第一个捕获组最近匹配的文本完全匹配两次
  • -
    按字面意思匹配连字符
    -
  • \1{2}
    与第一个捕获组最近匹配的文本完全匹配两次
  • -
    按字面意思匹配连字符
    -
  • \1{4}
    与第一个捕获组最近匹配的文本精确匹配四次
  • $
    在行尾断言位置

对于这十种您不希望看到的情况,使用
不处于
状态可能会更简单,以代替正则表达式。那么,是否给出(或者您已经在测试)字符串的正确格式为“xxx xx xxxx”,其中x代表数字?“还是你也需要检查一下?”mathguy说。列已具有“xxx xx xxxx”格式的数据。我只是指定了它,所以它会被覆盖。@Patrick这是我正在编写的巨型查询的一部分,所以我想让它通过reg exp进行过滤,而不是用10英寸或不英寸。但我明白了。
^(\d)\1{2}-\1{2}-\1{4}$