非捕获组中的正则表达式捕获组

2024-05-23 17:40:41 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,如何在非捕获组中捕获组?换言之,如何重复包含捕获组的非捕获子模式?在

一个例子是捕获导入字符串上的所有包名。E、 g.字符串:

import pandas, os, sys

会返回“pandas”、“os”和“sys”。以下模式捕获第一个包并到达第二个包:

import\s+([a-zA-Z0=9]*),*\s*

从这里开始,我想重复捕捉组并匹配以下字符的子模式,即([a-zA-Z0=9]*),*\s*。当我用一个非捕获组包围这个子模式并重复它时:

^{pr2}$

它不再捕获内部的组。在


Tags: 字符串importpandasossys模式字符例子
3条回答

一个重复捕获组将只捕获最后一个迭代。这就是为什么需要重新构造正则表达式以使用re.findall。在

\s*
(?:
  (?:^from\s+
    (  # Base (from (base) import ...)
      (?:[a-zA-Z_][a-zA-Z_0-9]*  # Variable name
        (?:\.[a-zA-Z_][a-zA-Z_0-9]*)*  # Attribute (.attr)
      )
    )\s+import\s+
  )
|
  (?:^import\s|,)\s*
)
(  # Name of imported module (import (this))
  (?:[a-zA-Z_][a-zA-Z_0-9]*  # Variable name
    (?:\.[a-zA-Z_][a-zA-Z_0-9]*)*  # Attribute (.attr)
  )
)
(?:
  \s+as\s+
  (  # Variable module is imported into (import foo as bar)
    (?:[a-zA-Z_][a-zA-Z_0-9]*  # Variable name
      (?:\.[a-zA-Z_][a-zA-Z_0-9]*)*  # Attribute (.attr)
    )
  )
)?
\s*
(?=,|$)  # Ensure there is another thing being imported or it is the end of string

Try it on regex101.com

捕获组0将是Base,捕获组1将是导入模块的名称(您要查找的内容),捕获组2将是该模块所在的变量(from (group 0) import (group 1) as (group 2)

^{pr2}$
[('', 'pandas', ''), ('', 'os', ''), ('', 'sys', '')]

如果不关心其他两个捕获组,可以将它们删除。在

您可以使用您的import\s+(?:([a-zA-Z0-9=]+),*\s*)*regex(我刚刚修复了0-9范围以匹配任何数字,并将=包含到末尾)并使用PyPi regex module访问组1捕获堆栈:

>>> import regex
>>> s = 'import pandas, os, sys'
>>> rx = regex.compile(r'^import\s+(?:([a-zA-Z0-9=]+),*\s*)*$')
>>> print([x.captures(1) for x in rx.finditer(s)])
[['pandas', 'os', 'sys']]

您的问题是严格按照regex来表达的,但是如果您愿意使用recursive descent parser(例如,^{}),那么许多需要regex专业知识的事情就会变得非常简单。在

例如,在这里你要的是

from pyparsing import *

p = Suppress(Literal('import')) + commaSeparatedList

>>> p.parseString('import pandas, os, sys').asList()
['pandas', 'os', 'sys']

>>> p.parseString('import                    pandas,             os').asList()
['pandas', 'os']

这可能是个人品味的问题,但对我来说

^{pr2}$

也比正则表达式更直观。在

相关问题 更多 >