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

时间:2015-07-01 20:30:33

标签: python regex matching regex-group

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

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

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

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

2 个答案:

答案 0 :(得分:2)

背景很重要:

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

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

那就是说,关于这个正则表达式有很多很愚蠢。我会考虑一下:

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

答案 1 :(得分:1)

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

  

与Python字符串文字一样,反斜杠后面可以跟各种字符,以指示各种特殊序列。它也用于转义所有元字符,因此您仍然可以在模式中匹配它们;例如,如果您需要匹配[\,则可以在它们前面加上反斜杠以删除其特殊含义:\[\\

在您的情况下,语句需要括号才能匹配,因为表达式中的每个\(\)后跟{{1} },这意味着前一个字符可以匹配任意次,包括 none。来自Python文档:

  

*与文字字符*不匹配;相反,它指定前一个字符可以匹配零次或多次,而不是恰好匹配一次。

因此,前三位数字附近有或没有括号的陈述可能会匹配。

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