mysql REGEXP精确模式匹配

时间:2018-09-27 13:08:18

标签: php mysql regex

我正在编写一个php脚本,该脚本将遍历数据库中的所有表并查找纯文本信用卡号。为此,我正在使用MySQL REGEXP。我只需要“仅”包含信用卡号的那些结果。如果有任何包含信用卡号的文本数据,则脚本不应考虑它。

例如

| id | ccno ||
| 1 | 4111111111111111 ||
| 2 | 4111 1111 1111 1111 ||
| 3 | 4111-1111-1111-1111 ||
| 4 |一些文字4111111111111111一些文字|

如果查询在上面的表上触发,那么它应该返回前3条记录,而不应该返回第4条记录。为此,我使用下面的查询,而我面临的问题是查询返回了所有4条记录。

SELECT ccno FROM aacc WHERE 
(ccno = REGEXP '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
OR ccno = REGEXP '[0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9] [0-9][0-9][0-9][0-9]'
OR ccno = REGEXP '[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')

3 个答案:

答案 0 :(得分:2)

尝试使用正则表达式^([0-9]{4}[-[:space:]]?){4}$

这将匹配由空格或连字符(可选)分隔的16个数字

regex

答案 1 :(得分:2)

已知有复杂的正则表达式来匹配大型信用卡提供商(例如Visa和MasterCard)的卡号。就您的问题而言,以下模式非常接近您想要的:

SELECT *
FROM yourTable
WHERE ccno REGEXP '^[0-9]{4}([[:space:]-]?[0-9]{4}){3}$';

Demo

此模式不完全正确,但是您的数据仍然没有匹配,例如,美国运通卡,其格式为dddd-dddddd-ddddd,带有两个破折号,而不是三个破折号。如果您打算使用生产数据进行此操作,则应研究如何将信用卡号与正则表达式匹配。

https://www.regular-expressions.info/creditcard.html

答案 2 :(得分:0)

尽管以上两个答案对我的需求有所帮助,但我现在编写了整个查询,该查询将与纯文本信用卡完全匹配。 此查询可正常使用的卡为:
美国运通
签证
万事达卡
发现

MySQL查询为:

SELECT *
FROM yourTable
WHERE (ccno REGEXP '^4[0-9]{3}([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^3[47][0-9]{2}[[:space:]-]?[0-9]{6}[[:space:]-]?[0-9]{5}$'
       OR ccno REGEXP '^6011([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^65[0-9]{2}([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^5[1-5][0-9]{2}([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^222[1-9]([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^2[3-6][0-9]{2}([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^27[01][0-9]([[:space:]-]?[0-9]{4}){3}$'
       OR ccno REGEXP '^2720([[:space:]-]?[0-9]{4}){3}$'
       );

可以看到工作示例here