【问题标题】:Normalize phone numbers using regex使用正则表达式规范化电话号码
【发布时间】:2012-06-26 06:34:50
【问题描述】:

我有一个未经验证的用户输入的电话号码列表,它们看起来像:

 - 495) 995-0595
 - 105-6439
 - 095 268 8621
 - 324-51-44
 - 7 (495) 995-05-95
 - 7 495 995 05 95
 - 7 (495) 995-0595
 - +7 (495) 995-05-95
 - 7 (495)925-34-89
 - 7(495)9253489
 - 7(495)925-34-89
 - 74959950595

我想将这些数字转换成这种(俄语)格式: +X (XXX) XXX-XX-XX

这里有没有机会使用正则表达式来实现它?

【问题讨论】:

  • 我猜你应该在用户输入数据时进行验证。
  • 看起来你只有两个场景,7位数字和11位数字。撇开格式不谈,您首先要从列表中删除所有格式,并将其存储为纯数字。然后使用 string.format 以任何你想要的方式格式化它
  • 你怎么知道在105-6439324-51-44 等短号码的缺失字段中填写什么?我们可以假设他们都是+7 (495)...吗?前导095+7 (495) 的简写吗?
  • 我猜这些数字在某种数据库中。除了“规范化”它们之外,我没有看到任何其他解决方案:提取数字并根据您的俄罗斯电话号码格式重新格式化它们。
  • 如果我有 105-6439 或 324-51-44 这样的数字,我必须使用莫斯科国际代码 (499) 对其进行格式化

标签: c# regex phone-number


【解决方案1】:

是的,提取并重新格式化!

List<string> oldlist = new List<string>();
List<string> newlist = new List<string>();
foreach(string s in oldlist)
{
     if(s.Contains('(')) s = s.Replace('('), "");//etc
     newlist.Add(numFormat(s));
}

string prefix = "495";

string numFormat(string s)
{
     string my;
     if(s.Length == 7)
     {
         my = string.Format("+7 ({0}) {1} {2} {3}", prefix, s.substring(0,3), s.subtring(3,2), s.substring(5,2);
     }
     else if(s.length == 10)
     {
         my = string.Format("+7 ({0}) {1} {2} {3}", s.substring(0,3), s.substring(3,3), s.subtring(5,2), s.substring(7,2);        
     }
     //etc
     return my;
}

这只是我的想法......但你明白了

【讨论】:

    【解决方案2】:

    通过此运行您的列表:

    var strippedNumbers = new List<string>();
    foreach (var num in listOfRussianNumbers.Select(x=>Regex.Replace(x, "[^0-9]", ""))) 
        strippedNumbers.Add(num.Length == 7?"7499"+num:num);
    

    然后使用 string.Format 以你想要的方式打印出来

    string.Format("+{0} ({1}) {2}-{3}-{4}", 
        num.Substring(0,1), 
        num.Substring(1,3),
    num.Substring(4,3),
    num.Substring(7,2),
    num.Substring(9,2));
    

    【讨论】:

    • 最后3个必须是num.Substring(4,2), num.Substring(6,2), num.Substring(8,2));
    • 不,我认为你错过了第一个数字,所以你的所有字符串都是 1 char off :)
    【解决方案3】:

    我认为你应该这样做

    1. 将其转换为字符串。
    2. 使用循环删除任何看起来不像数字的东西。您可以为此使用Char.IsDigit()
    3. 然后使用string.Substring() 进行所需的格式设置。

    确保您仅以字符串格式执行所有这些步骤。

    喜欢

    string str = "495) 995-0595";
    List<char> digits = new List<char>();
    
    for (int i = 0; i < str.Length; i++)
    {
        if(char.IsDigit(str[i]))
            digits.Add(str[i]);
    }
    
    str = new string(digits.ToArray());
    
    str = "+" + str.Substring(0, 1) + " (" + str.Substring(1, 3) + ") " 
          + str.Substring(4, 2) + "-" + str.Substring(6, 2) + "-" + str.Substring(8);
    

    这回了我"+4 (959) 95-05-95"

    【讨论】:

    • 问题是 495) 中缺少的圆括号定义了城市代码。所以我也必须解决这个问题,以获取 XXX-XX-XX 中的电话号码
    • 我认为您会在 Nikhil 和我的解决方案中发现我们忽略了所有错误的格式。剥离格式比“修复”格式容易得多。只需抓住数字,然后以正确的格式覆盖它。不要考虑尝试修复每个单独的格式化案例,坏案例有无限可能。
    【解决方案4】:

    这是我能在短时间内得到的最好结果。

    ((\+?\d)\s?)?\(?(\d\d\d)\)?\s?(\d\d\d)(\s|-)?(\d\d)(\s|-)?(\d\d)
    

    这将从您的示例中选择粗体。

    495) 995-0595
    105-6439
    095 268 8621
    324-51-44
    7 (495) 995-05-95
    7 495 995 05 95
    7 (495) 995 -0595
    +7 (495) 995-05-95
    7 (495)925-34-89
    7(495)9253489
    7(495)925-34-89
    74959950595

    对于不匹配的字符串,您可以通过不同的例程发送它们或进行手动处理。

    【讨论】:

      【解决方案5】:

      类似的东西:

      (\d)? ?\(?(\d\d\d)?\)? *?(\d\d\d) *?-? *?(\d\d) *?-? *?(\d\d)
      

      【讨论】:

        猜你喜欢
        • 2019-05-30
        • 1970-01-01
        • 2017-09-23
        • 2014-02-15
        • 2016-02-02
        • 2011-12-14
        • 2013-05-26
        • 1970-01-01
        相关资源
        最近更新 更多