当前位置: 首页 > 知识库问答 >
问题:

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

萧琛
2023-03-14

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

例如,捕获导入字符串上的所有包名。例如,字符串:

导入熊猫、操作系统、系统

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

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

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

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

它不再捕捉里面的群体。

共有3个答案

戚星腾
2023-03-14

您可以使用您的import\s(?:([a-zA-Z0-9=] ),*\s*)*regex(我刚刚修复了0-9范围以匹配任何数字并包含=到最后)并使用PyPi regex模块访问Group 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']]
文鸣
2023-03-14

重复捕获组只捕获最后一次迭代。这就是为什么你需要重组你的正则表达式来使用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

试试regex101.com

捕获组0将是,捕获组1将是(您所追求的)导入模块的名称,捕获组2将是模块所在的变量(从(组0)导入(组1)为(组2)

import re

regex = r"\s*(?:(?:^from\s+((?:[a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*))\s+import\s+)|(?:^import\s|,)\s*)((?:[a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*))(?:\s+as\s+((?:[a-zA-Z_][a-zA-Z_0-9]*(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*)))?\s*(?=,|$)"

print(re.findall(regex, "import pandas, os, sys"))
[('', 'pandas', ''), ('', 'os', ''), ('', 'sys', '')]

如果你不喜欢其他两个组,你可以删除它们。

濮俊美
2023-03-14

你的问题措辞严格是关于正则表达式的,但如果你愿意使用递归下降解析器(例如,pyparsing),许多需要正则表达式专业知识的事情就会变得非常简单。

例如,你的要求变成了

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']

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

Suppress(Literal('import')) + commaSeparatedList

也比正则表达式更直观。

 类似资料:
  • 本文向大家介绍PHP正则表达式之捕获组与非捕获组,包括了PHP正则表达式之捕获组与非捕获组的使用技巧和注意事项,需要的朋友参考一下 今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同时也希望有大神和细心的学习者找到我理解中

  • 我有一个带有(?:)格式的非捕获组的java正则表达式,我不明白为什么它为非捕获组提供“null”匹配。 如果我将下面的正则表达式缩短为“@te(st)(?:AA)?”使用相同的?:非捕获组,它给出了我认为的预期行为,只匹配1个组和完全匹配。

  • 我有一个带有(?:)格式的非捕获组的java正则表达式,我不明白为什么它为非捕获组提供“null”匹配。 如果我把下面的正则表达式缩短为“@te(st)(?:aa)?”用同样的非捕获组,它给出了我所期望的行为,只匹配1组和完全匹配。 参见下面的正则表达式: 结果: “@te(st)(?:aa)”的结果使用相同的代码: 第一个将非捕获组匹配为null的正则表达式是什么?

  • 假设我有这个虚拟URL,我需要提取植物及其颜色作为 下面的I have正在按预期捕获我需要的元素,但是当我的URL中的植物少于4株时,它无法捕获任何东西。底部有一个指向regex测试员的链接,其中有示例代码和URL,您可以使用。 如何修改这个正则表达式,使其动态工作,从而在不需要静态URL结构的情况下捕获可用内容。现在,假设我最多只能捕获4株植物(8组) https://regex101.com/

  • 我是一个完全的正则表达式新手,花了几个小时试图解决这个难题。我认为我必须使用某种可选的非捕获组或交替。 我想匹配以下字符串: > 诺伊尔电影 a von 1000 诺伊尔电影a von 1000 mit b 诺伊尔电影a von 1000 mit b und c 1000英镑的新电影 诺伊尔电影公司 诺伊尔电影a mit b und c 诺伊尔电影a mit b und c und 我的正则表达式

  • 问题内容: 我正在尝试使用Java expr在:之后捕获正确的部分,但是在以下代码中,打印的捕获组是整个字符串,怎么了? 问题答案: 子组的编号从1开始,全文为0。只需循环执行count + 1。