Python Regex返回引用命名组

时间:2018-02-10 17:54:47

标签: python regex python-3.x parsing regex-group

我试图解析可以通过不同方式发出的电话号码。例如:

(321) 123-4567
(321) 1234567
321-123-4567
321123-4567

然后,我想分别绘制这三个部分中的每一个。我的想法是使用命名组和一些或类似情况:

(^\s*(?P<area>[0-9]{3})\-?(?P<fst>[0-9]{3})\-(?P<lst>[0-9]{4}))|(^\s*\(\area\)\s*(\fst)\-?(\lst))

我认为,问题在于我没有正确地调用命名组。我试图使用https://regex101.com/来帮助但仍然卡住了。因为区号周围的括号应该既存在又不存在,我不想使用&#34;?&#34;字符如:

\(?(?P<area>[0-9]{3})\)?

任何人都可以帮我这个吗?非常感谢。

我正在使用python 3.6和重新打包。

2 个答案:

答案 0 :(得分:2)

你的正则表达式存在一些问题。您没有选中括号,并且您不允许区号和第一部分之间的可选空格。如果没有看到你的Python代码,你就不容易知道你是怎么做的,但我这样做是通过拆分成一个编译的正则表达式,然后使用正则表达式对数字列表。

from __future__ import print_function
import re

phone_numbers = [
'(321) 123-4567',
'(321) 1234567',
'321-123-4567',
'321123-4567',
]

regex = re.compile(r'^\s*\(?(?P<area>[0-9]{3})[) -]*(?P<fst>[0-9]{3})-?(?P<sec>[0-9]{4})')

for p in phone_numbers:
    print(regex.sub(r'(\g<area>) \g<fst>-\g<sec>', p))

这并不完美,因为它将允许解析不符合有效语法的内容(根据您的列表),但这不应该是一个问题。例如,'(321))- - )) 123-4567'将被正确解析。

答案 1 :(得分:1)

我使用小组测试:^(\()?(?P<area>\d{3})(?(1)\))[ -]?(?P<fst>\d{3})-?(?P<lst>\d{4})$

在那里:

  • (\()?在存在时捕获组1中的左括号。
  • (?(1)\))测试是否存在捕获的组1,如果匹配,则匹配关闭的括号。

其余的非常简单。