0

我正在编写一个匹配美国电话号码格式的代码

所以它应该匹配:

123-333-1111
(123)111-2222
123-2221111

但不应匹配 1232221111

matchThreeDigits = r"(?:\s*\(?[\d]{3}\)?\s*)"
matchFourDigits = r"(?:\s*[\d]{4}\s*)"
phoneRegex = '('+ '('+  matchThreeDigits + ')' + '-?' +   '('+  matchThreeDigits + ')' + '-?' + '(' + matchFourDigits + ')' +')';
matches = re.findall(re.compile(phoneRegex),line)

问题是我需要确保模式中至少存在 () 或 '-' 之一(否则它可以是九位数字而不是电话号码)。出于效率原因,我不想再做一次模式搜索。有没有办法在正则表达式模式本身中容纳这些信息。

4

3 回答 3

3

像这样的东西?

pattern = r'(\(?(\d{3})\)?(?P<A>-)?(\d{3})(?(A)-?|-)(\d{4}))'

使用它:

import re
regex = re.compile(pattern)
check = ['123-333-1111', '(123)111-2222', '123-2221111', '1232221111']
for number in check:
    match = regex.match(number)
    print number, bool(match)
    if match:
        # show the numbers
        print 'nums:', filter(lambda x: x and x.isalnum(), match.groups())

>>> 
123-333-1111 True
nums: ('123', '333', '1111')
(123)111-2222 True
nums: ('123', '111', '2222')
123-2221111 True
nums: ('123', '222', '1111')
1232221111 False

笔记:

您要求解释:(?P<A>-)(?(A)-?|-)

  • (?P<A>-) : 是一个名为 的命名捕获组A(?P<NAME> ... )
  • (?(A)-?|-):是一个检查命名组是否A捕获某些内容的组,如果是,则为是,否则为否捕获。(?(NAME)YES|NO)

help(re)如果您在 Python 解释器中做一个简单的操作,或者在 Google 中搜索 Python 正则表达式,那么所有这些都可以轻松学习......

于 2013-11-06T08:20:29.740 回答
3

您可以使用以下正则表达式:

regex = r'(?:\d{3}-|\(\d{3}\))\d{3}-?\d{4}'

假设这(123)1112222是可以接受的。

分别|充当 or和转义\(and 。\)()

于 2013-11-06T08:12:29.247 回答
2
import re
phoneRegex = re.compile("(\({0,1}[\d]{3}\)(?=[\d]{3})|[\d]{3}-)([\d]{3}[-]{0,1}[\d]{4})")
numbers = ["123-333-1111", "(123)111-2222", "123-2221111", "1232221111", "(123)-111-2222"]
for number in numbers:
    print bool(re.match(phoneRegex, number))

输出

True
True
True
False
False

你可以在这里看到这个正则表达式的解释:http ://regex101.com/r/bA4fH8

于 2013-11-06T08:21:15.497 回答