【问题标题】:Python Regex back reference a named groupPython Regex 反向引用命名组
【发布时间】:2018-02-10 17:54:47
【问题描述】:

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

(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 regex python-3.x parsing regex-group


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我会使用小组测试:^(\()?(?P&lt;area&gt;\d{3})(?(1)\))[ -]?(?P&lt;fst&gt;\d{3})-?(?P&lt;lst&gt;\d{4})$

    在那里:

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

    剩下的就很简单了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-13
      • 1970-01-01
      • 2015-09-03
      • 2013-09-23
      • 2017-11-11
      • 2011-03-03
      • 2018-02-11
      相关资源
      最近更新 更多