【问题标题】:Python regex optional capture group or lastindexPython 正则表达式可选捕获组或 lastindex
【发布时间】:2015-09-26 15:46:46
【问题描述】:

我正在使用 python 逐行搜索文件中的部分和子部分。

   *** Section with no sub section
  *** Section with sub section ***
           *** Sub Section ***
  *** Another section

部分以 0-2 个空格开头,后跟三个星号,子部分有 2+ 个空格,然后是星号。

我写出没有“***”的部分/子部分;目前(使用 re.sub)。

Section: Section with no sub section
Section: Section with sub section
Sub-Section: Sub Section
Section: Another Section

问题 1:是否有一个带有捕获组的 python 正则表达式可以让我将部分/子部分名称作为捕获组访问?

问题 2:正则表达式组如何允许我标识部分或子部分(可能基于 match.group 中 /content 的数量)?

示例(无效):

match=re.compile('(group0 *** )(group1 section title)(group2 ***)')
sectionTitle = match.group(1)
if match.lastindex = 0: sectionType = section with no subs
if match.lastindex = 1: sectionType = section with subs
if match.lastindex = 2: sectionTpe = sub section

以前的尝试 我已经能够使用单独的正则表达式和 if 语句来捕获部分或子部分,但我想一次完成所有操作。类似于下面的行;对第二组的贪婪有问题。

'(^\*{3}\s)(.*)(\s\*{3}$)'

我似乎无法让贪婪或可选组一起工作。 http://pythex.org/ 在这一点上非常有帮助。

另外,我尝试捕获星号“(*{3})”,然后根据找到的组数确定是部分还是子部分。

sectionRegex=re.compile('(\*{3})'
m=re.search(sectionRegex)
  if m.lastindex == 0:
       sectionName = re.sub(sectionRegex,'',line) 
       #Set a section flag
  if m.lastindex ==1:
       sectionName = re.sub(sectionRegex,''line)
       #Set a sub section flag.

谢谢 也许我完全错了。任何帮助表示赞赏。

最新更新 我一直在玩 Pythex、答案和其他研究。我现在花更多的时间来捕捉这些词:

^[a-zA-Z]+$

并计算星号匹配的数量以确定“级别”。我仍在寻找一个单一的正则表达式来匹配两个 - 三个“组”。可能不存在。

谢谢。

【问题讨论】:

  • 你不需要正则表达式,str.startswith 会做你想做的事,但如果两者都可以有 2 个空格和三个 ***,你有点搞砸了
  • 如何区分0-2个空格和2+个空格?
  • 您能否添加一个其他行的示例,这些行现在可能会出现line.lstrip().replace("***","") 将完全按照您的意愿行事
  • 剥离和替换命令不会产生节类型(主要节与子节)。

标签: python regex capture-group


【解决方案1】:

问题 1:是否有一个带有捕获组的 python 正则表达式可以 让我作为捕获组访问部分/子部分名称?

一个正则表达式来匹配两个 - 三个“组”。可能不存在

是的,可以做到。我们可以将条件分解为如下树:

  • 行首 + 0到2个空格
  • 2 种交替中的任何一种:
    1. *** + 任何文字[group 1]
    2. 1+ 个空格 + *** + 任何文字[group 2]
  • ***(可选)+ 行尾


而上面的树可以用模式来表示:

^[ ]{0,2}(?:[*]{3}(.*?)|[ ]+[*]{3}(.*?))(?:[*]{3})?$

注意 SectionSub-Section 被不同的组([group 1][group 2] 分别)。它们都使用相同的语法.*?,都使用lazy quantifier (the extra "?") 以允许匹配末尾的可选"***"


问题 2:正则表达式组如何允许我识别部分 或子部分(可能基于 match.group 中 /content 的数量)?

上述正则表达式仅在第 1 组中捕获 Sections,仅在第 2 组中捕获 Sub-Sections。为了更容易在代码中识别,我将使用 (?P<named> groups) 并使用 .groupdict() 检索捕获。

代码:

import re

data = """  *** Section with no sub section
  *** Section with sub section ***
           *** Sub Section ***
  *** Another section"""

pattern = r'^[ ]{0,2}(?:[*]{3}[ ]?(?P<Section>.*?)|[ ]+[*]{3}[ ]?(?P<SubSection>.*?))(?:[ ]?[*]{3})?$'
regex = re.compile(pattern, re.M)

for match in regex.finditer(data):
    print(match.groupdict())

''' OUTPUT:
{'Section': 'Section with no sub section', 'SubSection': None}
{'Section': 'Section with sub section', 'SubSection': None}
{'Section': None, 'SubSection': 'Sub Section'}
{'Section': 'Another section', 'SubSection': None}
'''

您可以使用以下方法之一,而不是打印字典,而是引用每个 Section/Subsection

match.group("Section")
match.group(1)
match.group("SubSection")
match.group(2)

【讨论】:

  • 非常详细,非常有帮助。谢谢!
【解决方案2】:

假设你的意思是小节有 3+ 个空格,你可以这样做:

import re

data = '''
  *** Section with no sub section
*** Section with sub section ***
           *** Sub Section ***
 *** Another section
'''

pattern = r'(?:(^ {0,2}\*{3}.*\*{3} *$)|(^ {0,2}\*{3}.*)|(^ *\*{3}.*\*{3} *$))'

regex = re.compile(pattern, re.M)
print regex.findall(data)

这将为您提供如下组:

[('', '  *** Section with no sub section', ''),
 ('*** Section with sub section ***', '', ''),
 ('', '', '           *** Sub Section ***'),
 ('', ' *** Another section', '')]

【讨论】:

    【解决方案3】:

    正则表达式:

    (^\s+)(\*{3})([a-zA-Z\s]+)(\*{3})*
    

    如下所述捕获 3 或 4 个组。

    Group 0: "(^\s+)" Captures whitespace
    Group 1: "(\*{3})" captures '***'
    Group 2:"([a-zA-Z\s]+)" captures alpha characters and spaces
    Group 3: "(\*{3})*" captures 0 or or more occurrences of "***"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多