【问题标题】:Regex for fetching multiple strings within brackets用于在括号内获取多个字符串的正则表达式
【发布时间】:2020-09-10 16:11:57
【问题描述】:

如何匹配下面字符串中 () 之间的 2 个不同组

data foo (drop = DISCOUNT price RENAME = ( PROV_NM1= PROV_NM PROV_ST_NM1 = PROV_ST_NM) where = ( product = 'whizmo' and product < 10 )) bar( drop= DISCOUNT price rename= ( startDate = beginDate ) );

我需要匹配这个以获得 2 个组:

  1. foo (drop = DISCOUNT price RENAME = ( PROV_NM1= PROV_NM PROV_ST_NM1 = PROV_ST_NM) where = ( product = 'whizmo' and product &lt; 10 ))
  2. bar( drop= DISCOUNT price rename= ( startDate = beginDate ) )

我这几天一直在安静地尝试它,并想出了这个正则表达式: (?i)(data)\s+((\w+)(?=(\s*))(?:\4\w+))?\s*(\(((.|\n)*?)\);)? 可以看这里:regex demo

它适用于大多数情况,但在上述示例中没有给出 2 个单独的组,因为它匹配单个组中括号内的所有内容。

我也尝试了一些递归模式,但遗憾的是无法弄清楚。对此的任何帮助或指导表示赞赏。谢谢。

【问题讨论】:

  • 看起来你需要递归或堆栈。编写一个简单的解析器可能更容易,或者如果这是一些标准符号,请使用现有的工业级解析器。不过,尚不完全清楚该符号的规范是什么。
  • 也许这个页面会有所帮助stackoverflow.com/a/35271017/5424988
  • 我确实尝试过为此使用递归,但它没有按预期工作,我们尝试的所有内容都与一个相同或不匹配。我们尝试的简单递归之一是:(?i)((\w+)(\s*=\s*)(\((.*?)\))?)(?5),但它与预期的不匹配。将解析器开发作为正则表达式的最后一个选项将有助于解决可能遇到的多种模式。
  • 对于规范,我们实际上是在尝试解析一些转换的 SAS 数据步骤语句。

标签: python-3.x regex pcre regex-group


【解决方案1】:

在 PCRE 中,您可以使用此递归正则表达式来捕获您想要的内容:

~(?: ^data | (?!^)\G ) \h+ ( \w+ \h* ( \( (?: [^()]*+ | (?-1) )* \) ) )~xi

RegEx Demo

您的比赛在捕获的第 1 组

中可用

正则表达式详细信息:

  • (?: ^data | (?!^)\G ):在一行中以data 开头,否则从上一个匹配项的结尾匹配,即\G
  • \h+: 匹配 1+ 个空格
  • (: 开始捕获组 #1
    • \w+: 匹配 1+ 个单词字符
    • \h*:匹配 0+ 个空格
    • (: 开始捕获组 #2
      • \(:匹配文字((开场)
      • (?::启动非捕获组
        • [^()]*+:匹配0个或多个不是()的字符
        • |:或者
        • (?-1):递归匹配最新组,即#2
      • )*:结束非捕获组。匹配此组中的 0 个或多个
    • ): 捕获组#2
  • ): 捕获组 #1

参考:RegEx Expression Recursion

【讨论】:

  • 这是一个很棒的模式,使用 \G 并递归最后一组 ++
  • 是的..!!它做了。谢谢阿努巴瓦。我也从中学到了很多新东西。您是否有任何参考或书籍建议您使用正则表达式变得更好?我一直在寻找一些参考资料,但真的找不到好的参考资料。再次感谢。 :)
  • 很高兴它有帮助。我添加了一个很好的正则表达式递归参考。您将在同一网站上阅读大量内容丰富的页面。
【解决方案2】:

这最多可以处理 1 级括号输入的嵌套:

\w+\s*\((?:\([^)]+\)|[^)])*?\)

live demo

它匹配一个单词后跟括号输入,但包含一个替代 在尝试更简单的非右括号匹配之前,优先使用外括号内的内括号输入。

【讨论】:

    【解决方案3】:

    我不是专家,但我会选择很多简单的选择

    foo = ‘(foo.+?)bar’
    bar = ‘(bar.+);’
    
    #or combine both 
    
    ‘(bar.+);|(foo.+?)bar’
    

    【讨论】:

      猜你喜欢
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 2011-07-17
      • 2010-09-29
      • 2013-01-16
      相关资源
      最近更新 更多