使用SQL REGEXP查找手机号码

时间:2012-11-08 07:06:03

标签: java mysql sql database


我们的数据库可以包含不同格式的手机号码,例如:'(731)123-4567'或'731-123 45 67'或'731-12-3- [4567]'等。
此外,我在API中搜索的输入可以是任何格式 因此,当我需要在db中找到一个带有移动设备的用户时,我清理输入数字,所以它看起来像'7311234567'然后用regexp '(\\+|\\-|\\(|\\)|\\[|\\]| )*'换行/填充它,所以例如,SQL看起来像这样:

select * from contact where mobile REGEXP '(\\+|\\-|\\(|\\)|\\[|\\]| )*
             1(\\+|\\-|\\(|\\)|\\[|\\]| )*7(\\+|\\-|\\(|\\)|\\[|\\]| )*
             3(\\+|\\-|\\(|\\)|\\[|\\]| )*1(\\+|\\-|\\(|\\)|\\[|\\]| )*
             2(\\+|\\-|\\(|\\)|\\[|\\]| )*9(\\+|\\-|\\(|\\)|\\[|\\]| )*
             8(\\+|\\-|\\(|\\)|\\[|\\]| )*0(\\+|\\-|\\(|\\)|\\[|\\]| )*
             7(\\+|\\-|\\(|\\)|\\[|\\]| )*4(\\+|\\-|\\(|\\)|\\[|\\]| )*
             0(\\+|\\-|\\(|\\)|\\[|\\]| )*';

问题是,当我得到像'7311234567'这样的输入,但是没有'73'时 - 当查询执行时 - 它也会找到具有'7311234567'的用户。
问题:如何更好地包装我的正则表达式,使其仅适用于正则表达式的完整数字?

3 个答案:

答案 0 :(得分:3)

这样的事情会起作用吗?它使用REPLACE而不是REGEX,但它似乎符合您的要求(是的,它有点令人作呕 - 请参阅SQLFiddle here以获得更清晰的视图)。您可以根据需要添加更多参数以进一步标记:

SET @num = '7311234567';

SELECT *
FROM mobile
WHERE 
  REPLACE(
    REPLACE(
      REPLACE(
        REPLACE(
          REPLACE(
            REPLACE(num, ' ', ''), '-', ''), '(', ''), ')', ''), '[', ''), ']', '')

  = 
  REPLACE(
    REPLACE(
      REPLACE(
        REPLACE(
          REPLACE(
            REPLACE(@num, ' ', ''), '-', ''), '(', ''), ')', ''), '[', ''), ']', '')

答案 1 :(得分:3)

您可以使用此MySQL packageregexp_replace随意使用。 然后,您可以在搜索时替换所有非数字字符,避免测试不同的格式。

String mobileInput = "(731) 123-4567";
String mobile = mobileInput.replaceAll("[^0-9]", "");

String sql = "select * from contact where regexp_replace(mobile, '[^0-9]', '') = ?";
// run your sql query

// or directly on database side without Java
String sql = "select * from contact where regexp_replace(mobile, '[^0-9]', '') = regexp_replace(?, '[^0-9]', '')";

删除非数字字符后,(731) 123-4567731-123 45 67731-12-3-[4567]将为您提供7311234567

使用Oracle测试,因为我没有安装MySQL:

select regexp_replace('(731) 123-4567', '[^0-9]', '') as "first",
       regexp_replace('731-123 45 67', '[^0-9]', '') as "second",
       regexp_replace('731-12-3-[4567]', '[^0-9]', '') as "third"
  from dual

- >

     first          second           third
7311234567      7311234567      7311234567

答案 2 :(得分:2)

如果您不想为此安装额外的软件包,则只​​需在正则表达式中添加开始和结束锚点:^$

您也可以将其简化为不那么冗长:

^[^0-9]*7[^0-9]*3[^0-9]*1[^0-9]*1[^0-9]*2[^0-9]*3[^0-9]*4[^0-9]*5[^0-9]*6[^0-9]*7[^0-9]*$

当然,最好的解决方案是在输入时规范化数据。