【问题标题】:What's the best way to format a phone number in Python?在 Python 中格式化电话号码的最佳方法是什么?
【发布时间】:2022-04-08 15:35:59
【问题描述】:

如果我只有一个 10 位或更多位的字符串,如何将其格式化为电话号码?

一些简单的例子:

555-5555
555-555-5555
1-800-555-5555

我知道这些不是格式化它们的唯一方法,如果我自己做的话,我很可能会遗漏一些东西。是否有 python 库或格式化电话号码的标准方法?

【问题讨论】:

  • 它们可能来自什么范围?不同国家/地区对电话号码格式有不同的约定。
  • 第二。请不要编写假定每个电话号码都是美国格式的代码。尝试使用这样的程序真的很烦人。
  • 看来写电话号码的标准方法叫做 E.123。所以国内号码看起来像(800) 555 5555,国际号码看起来像+1 800 555 5555。但不要忘记不同组的长度因国家/地区而异。 en.wikipedia.org/wiki/E.123
  • @Thomas 对,这正是我问是否有图书馆可以做到这一点的原因。很容易做出错误的假设。如果格式取决于区域,那么也许这应该是库中的参数或设置。
  • 地区可以从数字推断出来如果包含国家代码(美国国家代码为1)。

标签: python formatting format standards libs


【解决方案1】:

对于图书馆:电话号码(pypisource

用于解析、格式化、存储和验证国际电话号码的 Google 通用库的 Python 版本。

自述文件不足,但我发现代码有据可查。

【讨论】:

  • 对于那些寻找快速答案的人,这里有一个带有美国号码的样本。 pip install phonenumbers 然后import phonenumbers phonenumbers.format_number(phonenumbers.parse("8006397663", 'US'), phonenumbers.PhoneNumberFormat.NATIONAL)
  • 如何在这个库中使用自定义格式?我需要 {CountryCode}-\d{3}-{remaining_numbers}
  • github 上的自述文件很棒。 github.com/daviddrysdale/python-phonenumbers
  • @ShaneReustle:你的评论和答案一样好8^D
【解决方案2】:

似乎您的示例格式化为除最后一位之外的三位数组,您可以编写一个简单的函数,使用千位分隔符并添加最后一位:

>>> def phone_format(n):                                                                                                                                  
...     return format(int(n[:-1]), ",").replace(",", "-") + n[-1]                                                                                                           
... 
>>> phone_format("5555555")
'555-5555'
>>> phone_format("5555555")
'555-5555'
>>> phone_format("5555555555")
'555-555-5555'
>>> phone_format("18005555555")
'1-800-555-5555'

【讨论】:

    【解决方案3】:

    这里有一个改编自 utdemir's solutionthis solution 的版本,适用于 Python 2.6,因为 "," 格式化程序是 Python 2.7 中的新功能。

    def phone_format(phone_number):
        clean_phone_number = re.sub('[^0-9]+', '', phone_number)
        formatted_phone_number = re.sub("(\d)(?=(\d{3})+(?!\d))", r"\1-", "%d" % int(clean_phone_number[:-1])) + clean_phone_number[-1]
        return formatted_phone_number
    

    【讨论】:

      【解决方案4】:

      您可以使用库 DataPrep 中的函数 clean_phone()。使用pip install dataprep 安装它。

      >>> from dataprep.clean import clean_phone
      >>> df = pd.DataFrame({'phone': ['5555555', '5555555555', '18005555555']})
      >>> clean_phone(df, 'phone')
      Phone Number Cleaning Report:                                                   
          3 values cleaned (100.0%)
      Result contains 3 (100.0%) values in the correct format and 0 null values (0.0%)
               phone     phone_clean
      0      5555555        555-5555
      1   5555555555    555-555-5555
      2  18005555555  1-800-555-5555
      

      【讨论】:

        【解决方案5】:

        更详细,一个依赖项,但保证大多数输入的输出一致并且写起来很有趣:

        import re
        
        def format_tel(tel):
            tel = tel.removeprefix("+")
            tel = tel.removeprefix("1")     # remove leading +1 or 1
            tel = re.sub("[ ()-]", '', tel) # remove space, (), -
        
            assert(len(tel) == 10)
            tel = f"{tel[:3]}-{tel[3:6]}-{tel[6:]}"
        
            return tel
        

        输出:

        >>> format_tel("1-800-628-8737")
        '800-628-8737'
        >>> format_tel("800-628-8737")
        '800-628-8737'
        >>> format_tel("18006288737")
        '800-628-8737'
        >>> format_tel("1800-628-8737")
        '800-628-8737'
        >>> format_tel("(800) 628-8737")
        '800-628-8737'
        >>> format_tel("(800) 6288737")
        '800-628-8737'
        >>> format_tel("(800)6288737")
        '800-628-8737'
        >>> format_tel("8006288737")
        '800-628-8737'
        

        没有幻数; ...如果您不了解整个简洁性:

        def format_tel(tel):
            AREA_BOUNDARY = 3           # 800.6288737
            SUBSCRIBER_SPLIT = 6        # 800628.8737
            
            tel = tel.removeprefix("+")
            tel = tel.removeprefix("1")     # remove leading +1, or 1
            tel = re.sub("[ ()-]", '', tel) # remove space, (), -
        
            assert(len(tel) == 10)
            tel = (f"{tel[:AREA_BOUNDARY]}-"
                   f"{tel[AREA_BOUNDARY:SUBSCRIBER_SPLIT]}-{tel[SUBSCRIBER_SPLIT:]}")
        
            return tel
        

        【讨论】:

        • 太好了,谢谢。
        【解决方案6】:

        一个简单的解决方案可能是从后面开始,在四个数字后插入连字符,然后以三个为一组,直到到达字符串的开头。我不知道内置函数或类似的东西。

        您可能会发现这很有帮助: http://www.diveintopython3.net/regular-expressions.html#phonenumbers

        如果您接受用户输入的电话号码,正则表达式将很有用。我不会使用上面链接中遵循的确切方法。更简单的事情,比如去掉数字,可能更容易而且同样好。

        此外,在数字中插入逗号是一个类似的问题,已在其他地方得到有效解决,并且可以适应这个问题。

        【讨论】:

        • 图书链接已失效
        • 我修复了链接。
        【解决方案7】:

        就我而言,我需要按国家/地区获取类似“*** *** ***”的电话模式。

        所以我在我们的项目中重新使用了phonenumbers

        from phonenumbers import country_code_for_region, format_number, PhoneMetadata, PhoneNumberFormat, parse as parse_phone
        import re
        
        def get_country_phone_pattern(country_code: str):
            mobile_number_example = PhoneMetadata.metadata_for_region(country_code).mobile.example_number
            formatted_phone = format_number(parse_phone(mobile_number_example, country_code), PhoneNumberFormat.INTERNATIONAL)
            without_country_code = " ".join(formatted_phone.split()[1:])
            return re.sub("\d", "*", without_country_code)
        
        get_country_phone_pattern("KG")  # *** *** ***
        

        【讨论】:

          猜你喜欢
          • 2013-10-08
          • 1970-01-01
          • 2012-11-23
          • 1970-01-01
          • 2010-10-27
          • 2015-10-02
          • 2022-12-21
          • 1970-01-01
          相关资源
          最近更新 更多