【问题标题】:Capturing all matches in quantified regular expression捕获量化正则表达式中的所有匹配项
【发布时间】:2014-12-03 15:18:30
【问题描述】:

我正在尝试使用正则表达式从字符串中捕获重复的模式。更准确地说,我正在尝试解析 LDAP 模式定义。

示例字符串:

( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )

匹配字符串和所有相关组件的正则表达式(Python/扩展正则表达式)是:

^\( (?P<oid>\d+(\.\d+)*) ((?P<keyword>[A-Z-]+) (?P<value>[^' ]+|'[^']+'|\(.+\)) )+\)$

我已经命名了相关的匹配组。问题是我如何捕捉所有出现的 P 和 P?默认情况下,仅捕获最后一次出现,而仅匹配其他出现。

【问题讨论】:

  • 你为什么不在 Stack Overflow 上提问? meta.stackexchange.com/a/129632/165773
  • @gnat 为什么我不应该问程序员?
  • 这个问题属于 StackOverflow,因为它是关于一个实现问题。
  • 您是否检查了先前评论中提到的meta guidance? “如果您的代码或 IDE 不起作用,请继续询问...”等
  • '' 不是有效值吗?

标签: string regex string-matching


【解决方案1】:

如果您使用允许存储重复捕获组的结果的new regex module,您有一种方法,例如:

import regex

line = '''( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' X-BINARY-TRANSFER-REQUIRED 'TRUE' X-NOT-HUMAN-READABLE 'TRUE' )'''

pattern = r'''(?x) # switch the VERBOSE (free-spacing) mode on
^                  
\( [ ]*
(?P<oid>\d+(?:\.\d+)*) \s+  # use a non-capturing group when there is
(?:                         # no need to capture something
    (?P<keyword>[A-Z-]+) [ ]+
    (?P<value> [^' ]+ | '[^']*' | \(.+\)) [ ]*
)+
\)
$ 
'''

m = regex.match(pattern, line)
print m.capturesdict()

您获得:

{'oid': ['1.3.6.1.4.1.1466.115.121.1.8'], 'keyword': ['DESC', 'X-BINARY-TRANSFER-REQUIRED', 'X-NOT-HUMAN-READABLE'], 'value': ["'Certificate'", "'TRUE'", "'TRUE'"]}

关于子模式\(.+\)

这看起来像是一种处理嵌套括号的奇怪方式(因为贪婪的量词)。但是如果括号之间只有一个值,则此子模式将给出预期的结果。

还有一次,新的正则表达式模块允许您重用子模式(在捕获组中定义),允许构建递归模式,例如:

(\((?>[^()]+|(?1))*\))

(其中(?1) 指的是捕获组 1 中的模式(子模式本身))

所以,你可以像这样重写 value 子模式:

(?P<value> [^' ]+ | '[^']*' | (\((?>[^()]+|(?1))*\)) )

注意:但如果您不尝试处理嵌套括号,请忘记这一点并使用\([^)]*\)

【讨论】:

  • 我使用\(.+\) 作为占位符只是因为我还没有完成模式的编写;)。
猜你喜欢
  • 2016-10-28
  • 2013-05-09
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 2010-12-03
  • 2014-06-26
  • 2012-03-31
相关资源
最近更新 更多