使用oracle REGEXP_LIKE函数

时间:2017-11-21 17:23:33

标签: regex oracle

我正在尝试使用短划线( - )过滤掉具有相同数字的SSN。意味着SSN中的所有数字都相同并遵循xxx-xx-xxxx格式。

示例:

更正过滤后的值:111-11-1111,000-00-0000。

错误的过滤值:123-45-6789,012-34-5678

数据在Oracle数据库中,所以我使用REGEXP_LIKE函数,我的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}$');

您可以在https://regex101.com/r/rA2xA2/13

测试正则表达式

以上查询不会返回任何数据!

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

那么我错过了什么?

2 个答案:

答案 0 :(得分:2)

这是一种有趣(但正确!)的方式来检查社会安全号码中的“所有数字是否相等”。假设:输入字符串的长度恰好为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_NUMERIC_CHARACTERS参数中执行此操作:我将,声明为小数点分隔符,将-声明为“组”分隔符。 Oracle允许“组”分隔符出现在任何地方 - 由于这个原因,它被称为“组”而不是“数千”分隔符。在某些文化中,群体不一定是数千;例如,1亿的常见印度符号是10,00,00,000 - 而Oracle则适应这种情况。通过这样做,它也适应我的黑客 - 在方便的时候使用“组分隔符”,即使这不是预期的含义。

其余的都是微不足道的;当且仅当它可被111111111整除时,九位数字才具有相等的数字。

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

答案 1 :(得分:2)

代码

See regex in use here

^(\d)\1{2}-\1{2}-\1{4}$

说明

  • ^在行首处断言位置
  • (\d)将任何数字捕获到捕获组1
  • \1{2}匹配与第一个捕获组最近匹配的文本相同的文本
  • -字面上匹配连字符-
  • \1{2}匹配与第一个捕获组最近匹配的文本相同的文本
  • -字面上匹配连字符-
  • \1{4}匹配与第一个捕获组最近匹配的文本相同的文本
  • $断言行尾的位置