我正在尝试使用短划线( - )过滤掉具有相同数字的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,这是正确的行为,但错误的要求。
那么我错过了什么?
答案 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)
^(\d)\1{2}-\1{2}-\1{4}$
^
在行首处断言位置(\d)
将任何数字捕获到捕获组1 \1{2}
匹配与第一个捕获组最近匹配的文本相同的文本-
字面上匹配连字符-
\1{2}
匹配与第一个捕获组最近匹配的文本相同的文本-
字面上匹配连字符-
\1{4}
匹配与第一个捕获组最近匹配的文本相同的文本$
断言行尾的位置