正则表达式子电话号码格式在同一个字符串上多次

时间:2017-03-13 01:48:56

标签: python regex

我尝试使用reg表达式修改列表中的电话号码格式。 这是一个示例列表:

["(123)456-7890 (321)-654-0987",
"(111) 111-1111",
"222-222-2222",
"(333)333.3333",
"(444).444.4444",
"blah blah blah (555) 555.5555",
"666.666.6666 random text"]

每个有效数字都有字符串字符前导的空格或开头,以及字符串字符尾部的空格或结尾。这意味着字符串中可以有随机文本,或者一行中可以有多个数字。我的问题是:如何使用下面的匹配模式修改所有电话号码的格式?

我已编写以下模式以匹配所有有效格式:

 p = re.compile(r"""
  (((?<=\ )|(?<=^))             #space or start of string
  ((\([0-9]{3}\))|[0-9]{3})     #Area code
  (((-|\ )?[0-9]{3}-[0-9]{4})   #based on '-'
  |                             #or
  ((\.|\ )?[0-9]{3}\.[0-9]{4})) #based on '.'
  (?=(\ |$)))                   #space or end of string
 """, re.X)

我想修改数字,使其符合以下格式:

\(\d{3}\)d{3}-\d{4}  #Ex: (123)456-7890

我尝试使用re.findall和re.sub但没有运气。我对如何处理一条线上存在多个匹配的情况感到困惑。

编辑:所需的输出:

["(123)456-7890 (321)654-0987",
"(111)111-1111",
"(222)222-2222",
"(333)333-3333",
"(444)444-4444",
"blah blah blah (555)555-5555",
"(666)666-6666 random text"]

1 个答案:

答案 0 :(得分:1)

这是一个更简单的解决方案,适用于所有这些情况,虽然有点幼稚(并不关心匹配括号)。

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

替换为:

(\1)\2-\3

Try it online

<强>解释

首先使用\(?(\d{3})\)?检查3位数字,并选择左右括号。请注意,3个数字位于捕获组中。

接下来,它会检查一个可选的分隔符,然后检查另外3个数字,这些数字也存储在一个捕获组中:[ -.]?(\d{3})

最后,它再次执行上一步 - 但使用4位而不是3位数:[ -.]?(\d{4})

<强>的Python:

要在Python中使用它,您应该能够迭代列表中的每个元素并执行:

p.sub('(\\1)\\2-\\3', myString) # Note the double backslashes, or...
p.sub(r'(\1)\2-\3', myString)   # Raw strings work too

Example Python code

修改

这个解决方案有点复杂,并且确保如果有一个小括号,则必须有一个开始括号。

(\()?((?(1)\d{3}(?=\))|\d{3}(?!\))))\)?[ -.]?(\d{3})[ -.]?(\d{4})

替换为:

(\2)\3-\4

Try it online