拒绝区号之后和本地号码(美国)之前的可选空格

Reject optional whitespaces after area code and before local number (US)

我有一个将美国 phone 数字解析为 3 个字符串的正则表达式。

import re
s = '  916-2221111 ' # this also works'(916) 222-1111   '

reg_ph = re.match(r'^\s*\(?(\d{3})\)?-? *(\d{3})-? *-?(\d{4})', s)
if reg_ph:
    return reg_ph.groups()

else:
    raise ValueError ('not a valid phone number')

它完美地处理数字:

'(916) 222-1111   '
'  916-2221111 '

现在我需要添加一个额外的正则表达式来为

等数字生成值错误
s = '916 111-2222' # there are white spaces between the area code and a local number and NO ')'

我试过了

reg_ph = re.match(r'^\s*\(?(\d{3})\)?\s*-? *(\d{3})-? *-?(\d{4})', s)
reg_ph = re.match(r'^\s*\(?(\d{3})\)?s*-? *(\d{3})-? *-?(\d{4})', s)

但不拒绝有问题的字符串

我将不胜感激任何想法。我是正则表达式的新手!

在 Python 中,您可以使用条件语句来检查第 1 组是否有左括号。

如果是这种情况,请匹配右括号、可选空格和 3 位数字。否则匹配 - 和 3 位数字。

如果使用re.match可以省略^

^\s*(\()?\d+(?(1)\)\s*\d{3}|-\d{3})-?\d{4}

如果要匹配整个字符串和尾随空白字符:

^\s*(\()?\d+(?(1)\)\s*\d{3}|-\d{3})-?\d{4}\s*$

在部分中,模式匹配:

  • ^ 字符串开头
  • \s* 匹配可选的空白字符
  • (\()?可选组1,匹配(
  • \d+ 匹配 1+ 个数字
  • (? 有条件的
    • (1)\)\s*\d{3} 如果第 1 组存在,则匹配结尾 )、可选的空白字符和 3 位数字
    • |
    • -?匹配可选-
    • \d{3} 匹配 3 个数字
  • ) 关闭条件
  • -?\d{4}匹配可选-和4位数字

看到一个regex demo

例如,在模式中使用捕获组来获取数字:

import re

strings = [' (916) 111-2222',' 916-2221111 ', '916 111-2222']
pattern =r'\s*(\()?(\d+)(?(1)\)\s*(\d{3})|-(\d{3}))-?(\d{4})\s*$'

for item in strings:
  m=re.match(pattern, item)
  if m:
    t = tuple(s for s in m.groups() if s is not None and s.isdigit())
    print(t)
  else:
    print("no match for " + item)

输出

('916', '111', '2222')
('916', '222', '1111')
no match for 916 111-2222

Python demo