【问题标题】:Find phone numbers in python script在 python 脚本中查找电话号码
【发布时间】:2011-04-21 14:10:48
【问题描述】:

以下 python 脚本允许我使用正则表达式从给定文件中抓取电子邮件地址。

如何添加此内容以便我也可以获取电话号码?比如说,如果是 7 位或 10 位(带区号),还要考虑括号?

我当前的脚本可以在下面找到:

# filename variables
filename = 'file.txt'
newfilename = 'result.txt'

# read the file
if os.path.exists(filename):
        data = open(filename,'r')
        bulkemails = data.read()
else:
        print "File not found."
        raise SystemExit

# regex = something@whatever.xxx
r = re.compile(r'(\b[\w.]+@+[\w.]+.+[\w.]\b)')
results = r.findall(bulkemails)
emails = ""
for x in results:
        emails += str(x)+"\n"

# function to write file
def writefile():
        f = open(newfilename, 'w')
        f.write(emails)
        f.close()
        print "File written."

电话号码的正则表达式:

(\d{3}[-\.\s]\d{3}[-\.\s]\d{4}|\(\d{3}\)\s*\d{3}[-\.\s]\d{4}|\d{3}[-\.\s]\d{4})

电话号码的另一个正则表达式:

(?:(?:\+?1\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?

【问题讨论】:

  • 你有电话号码的正则表达式供我们批评吗?
  • 我刚刚在我的帖子中添加了我所拥有的电话号码。难以检测没有连字符的 7 位或 10 位数字。
  • 只有一个“国家”/系统还是全世界?您需要区分手机/移动电话和固定电话吗?您需要区分特殊用途的数字,例如 800 数字吗?可能的 + 前缀?
  • 我希望保持相对简单。所以不用担心国家代码。它应该能够接受带或不带括号的区号。或者也只是简单的 7 位数字。不需要区分数字,例如 800 个数字。

标签: python regex


【解决方案1】:

虽然这些都是简单的解决方案,但它们都不适用于北美。问题在于区号和交换号码不能以零或一开头。

r"(\\(?[2-9]\d{2}\\)?[ -])?[2-9]\d{2}-\d{4}"

将是解析 7 位或 10 位电话号码的正确方法。
(202) 555-4111
(202)-555-4111
202-555-4111
555-4111
都会正确解析。

【讨论】:

    【解决方案2】:
     //search phone number using regex in python
    
     //form the regex according to your output
    
    
     // with this you can get single mobile number
    
    
    
    phoneRegex = re.compile(r"\d\d\d-\d\d\d-\d\d\d\d")
    
    Mobile = phoneRegex.search("my number is 123-456-6789")
    
    print(Mobile.group())
    
    Output: 123-456-6789
    
    
    phoneRegex1 = re.compile(r"(\d\d\d-)?\d\d\d-\d\d\d\d")
    
    Mobile1 = phoneRegex1.search("my number is 123-456-6789")
    
    print(Mobile1.group())
    
    Output: 123-456-789
    
    
    Mobile1 = phoneRegex1.search("my number is 456-6789")
    
    print(Mobile1.group())
    
    Output: 456-678
    

    【讨论】:

      【解决方案3】:

      以下是上述答案的完成。这个正则表达式还能够检测国家代码:

      ((?:\+\d{2}[-\.\s]??|\d{4}[-\.\s]??)?(?:\d{3}[-\.\s]??\d{3}[-\.\s]??\d{4}|\(\d{3}\)\s*\d{3}[-\.\s]??\d{4}|\d{3}[-\.\s]??\d{4}))
      

      它可以检测以下样本:

      000-000-0000
      000 000 0000
      000.000.0000
      
      (000)000-0000
      (000)000 0000
      (000)000.0000
      (000) 000-0000
      (000) 000 0000
      (000) 000.0000
      
      000-0000
      000 0000
      000.0000
      0000000
      0000000000
      (000)0000000
      
      # Detect phone numbers with country code
      +00 000 000 0000
      +00.000.000.0000
      +00-000-000-0000
      +000000000000
      0000 0000000000
      0000-000-000-0000
      00000000000000
      +00 (000)000 0000
      0000 (000)000-0000
      0000(000)000-0000 
      

      【讨论】:

        【解决方案4】:

        由于还没有人发布这个正则表达式,我会的。这是我用来查找电话号码的。它匹配您在美国看到的所有常规电话号码格式。我不需要这个正则表达式来匹配国际号码,所以我没有为此目的对正则表达式进行调整。

        phone_number_regex_pattern = r"\(?\d{3}\)?[-.\s]\d{3}[-.\s]\d{4}"
        

        如果您想要匹配中间没有字符的简单电话号码,请使用此模式。例如:“4441234567”。

        phone_number_regex_pattern = r"\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}"
        

        【讨论】:

          【解决方案5】:

          您可以查看:http://regex.inginf.units.it/。使用一些训练数据和目标,它会为您构建一个合适的正则表达式。它并不总是完美的(检查 F 分数)。让我们用 15 个例子来试试吧:

          re.findall("\w\d \w\w \w\w \w\w \w\d|(?<=[^\d][^_][^_] )[^_]\d[^ ]\d[^ ][^ ]+|(?<= [^<]\w\w \w\w[^:]\w[^_][^ ][^,][^_] )(?: *[^<]\d+)+",  
                     """Lorem ipsum ©  04-42-00-00-00 dolor 1901 sit amet, consectetur +33 (0)4 42 00 00 00 adipisicing elit. 2016 Sapiente dicta fugit fugiat hic 04 42 00 00 00 aliquam itaque 04.42.00.00.00 facere, 13205 number: 100 000 000 00013 soluta. 4 Totam id dolores!""")
          

          返回['04 42 00 00 00', '04.42.00.00.00', '04-42-00-00-00', '50498,'] 添加更多示例以获得精确度

          【讨论】:

          • 简单的“4441234567”号码失败
          • 如果有更多的例子,解决方案会更好(15 太短了)
          【解决方案6】:

          对于西班牙电话号码,我使用这个非常成功:

          re.findall( r'[697]\d{1,2}.\d{2,3}.\d{2,3}.\d{0,2}',str)
          

          【讨论】:

            【解决方案7】:

            这是构建电话号码抓取正则表达式的过程。

            首先,我们需要匹配一个区号(3位)、一个中继(3位)和一个分机(4位):

            reg = re.compile("\d{3}\d{3}\d{4}")
            

            现在,我们要捕获匹配的电话号码,因此我们在我们有兴趣捕获的部分(全部)周围添加括号:

            reg = re.compile("(\d{3}\d{3}\d{4})")
            

            区号、中继线和分机号最多可以用 3 个非数字字符分隔(例如空格与连字符/点分隔符一起使用的情况):

            reg = re.compile("(\d{3}\D{0,3}\d{3}\D{0,3}\d{4})")
            

            现在,电话号码实际上可能以 ( 字符开头(如果区号括在括号中):

            reg = re.compile("(\(?\d{3}\D{0,3}\d{3}\D{0,3}\d{4}).*?")
            

            现在整个电话号码很可能嵌入在一堆其他文本中:

            reg = re.compile(".*?(\(?\d{3}\D{0,3}\d{3}\D{0,3}\d{4}).*?")
            

            现在,其他文本可能包含换行符:

            reg = re.compile(".*?(\(?\d{3}\D{0,3}\d{3}\D{0,3}\d{4}).*?", re.S)
            

            享受吧!

            我个人到此为止,但如果您真的想确保仅使用空格、连字符和点作为分隔符,那么您可以尝试以下方法(未经测试):

            reg = re.compile(".*?(\(?\d{3})? ?[\.-]? ?\d{3} ?[\.-]? ?\d{4}).*?", re.S)
            

            【讨论】:

              【解决方案8】:

              我认为这个正则表达式对于解析电话号码非常简单

              re.findall("[(][\d]{3}[)][ ]?[\d]{3}-[\d]{4}", lines)
              

              【讨论】:

                【解决方案9】:

                如果您对学习 Regex 感兴趣,可以尝试自己编写。这并不像想象的那么难。 RegexPal 之类的网站允许您输入一些测试数据,然后针对该数据编写和测试正则表达式。使用 RegexPal,尝试添加一些您希望找到的各种格式的电话号码(使用括号、区号等),获取 Regex cheatsheet 并查看您能走多远。如果不出意外,它将有助于阅读其他人的表达方式。

                编辑: 这是您的 Regex 的修改版本,它还应该匹配 7 位和 10 位电话号码,没有任何连字符、空格或点。我在字符类([]s)之后添加了问号,这使得它们中的任何内容都是可选的。我在 RegexPal 中对其进行了测试,但由于我仍在学习 Regex,我不确定它是否完美。试试看吧。

                (\d{3}[-\.\s]??\d{3}[-\.\s]??\d{4}|\(\d{3}\)\s*\d{3}[-\.\s]??\d{4}|\d{3}[-\.\s]??\d{4})
                

                它与 RegexPal 中的以下值匹配:

                000-000-0000
                000 000 0000
                000.000.0000
                
                (000)000-0000
                (000)000 0000
                (000)000.0000
                (000) 000-0000
                (000) 000 0000
                (000) 000.0000
                
                000-0000
                000 0000
                000.0000
                
                0000000
                0000000000
                (000)0000000
                

                【讨论】:

                • 谢谢,我发现 RegexPal 很有帮助。我添加到我的帖子中,并包括了到目前为止我所拥有的电话号码。我遇到的困难是检测 7 位或 10 位完全没有连字符的数字。
                • @Aaron,我尝试修改您提供的正则表达式来解决您的问题。它包含在我编辑的答案中。试一试,看看它是否有效。
                • 这看起来真的很棒。我刚刚做了一些测试,似乎工作得很好。我唯一的问题是,如何实现它以便它可以与我现有的电子邮件地址一起使用?有没有一种不需要太多工作的方法来做到这一点?再次感谢
                • 您应该能够以类似于已经实现电子邮件正则表达式的方式来实现它;尝试修改# regex = something@whatever.xxx 块的副本。我会试一试,但我以前从未接触过 Python。您只需在打开的文件中搜索与电话号码 Regex 匹配的内容,并将它们输出到result.txt
                • 您好,您的项目进展如何?你实现了吗?
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-01-13
                • 1970-01-01
                相关资源
                最近更新 更多