正则表达式“\”字符和分组“()”字符如何协同工作?

How does the regex "\" character and grouping "()" character work together?

我正在尝试查看以下模式匹配的语句:

\(*[0­-9]{3}\)*-­*[0-­9]{3}­\d\d\d+

我有点困惑,因为分组字符 () 前面有一个 \。这是否意味着该语句必须具有 ()?这是否意味着没有 () 的语句是不匹配的?

Statements:
'404­678­2347'
'(123)­1247890'
'456­900­900'
'(678)­2001236'
'404123­1234'
'(404123­123'

上下文很重要:

  • re.match(r'\(', content) 匹配文字括号。
  • re.match(r'\(*', content) 匹配 0 个或多个文字括号,从而使括号成为可选的(并允许多个括号,但这显然是一个错误)。

由于预期的行为不是“0 或更多”而是“0 或 1”,因此应该改为 r'\(?'


就是说,这个正则表达式有很多愚蠢之处。我会考虑:

[(]?\d{3}[)]?-?\d{6,}
  • 使用 [(]? 避免了反斜杠,因此无论是由 str() 还是 repr()(转义反斜杠)呈现的内容都更易于阅读。
  • 混合使用 [0-9]\d 是愚蠢的;最好选择一个并坚持下去。
  • 使用 * 代替 ? 是愚蠢的,除非你 真的 想要匹配 (((123))456-----7890.
  • \d{3}\d\d\d+ 匹配三个数字,然后匹配三个或更多附加数字。为什么不首先匹配六个或更多数字?

通常情况下,括号会充当分组字符,但是当正则表达式元字符前面有反斜杠时,它们会简单地简化为原始字符。来自 Python 文档:

As in Python string literals, the backslash can be followed by various characters to signal various special sequences. It’s also used to escape all the metacharacters so you can still match them in patterns; for example, if you need to match a [ or \, you can precede them with a backslash to remove their special meaning: \[ or \.

在您的例子中,语句 不需要 来匹配括号,因为表达式中的每个 \(\) 后跟a *,这意味着前一个字符可以匹配任意次数,包括 none。来自 Python 文档:

* doesn’t match the literal character *; instead, it specifies that the previous character can be matched zero or more times, instead of exactly once.

因此前 3 位数字周围有或没有括号的语句可能匹配。

来源:https://docs.python.org/2/howto/regex.html