Skip to main content
 首页 » 编程设计

Python 正则表达式反向引用命名组

2024年08月16日38zhujiabin

我正在尝试解析可以通过不同方式获得的电话号码。例如:

(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/ 来提供帮助,但仍然卡住了。因为区号周围的括号要么都存在,要么都不存在,所以我不想使用“?”像这样的字符:

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

谁能帮我解决这个问题?太感谢了。

我正在使用 python 3.6 和 re 包。

请您参考如下方法:

您的正则表达式存在一些问题。您没有将方括号设为可选,并且您不允许在区号和第一部分之间使用可选空格。如果没有看到您的 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' 将被正确解析。