【问题标题】:Regular Expression, match characters outside curly braces { }正则表达式,匹配大括号 { } 外的字符
【发布时间】:2012-12-27 02:58:52
【问题描述】:

我有以下数据:

int  time="1356280261"
char value="3000"

bankLine {
  char value="3000"
  char currency="EUR"
  int  time="1356280261"
} #bankLine

我正在递归解析这些数据,只想分别匹配块外的 2 个变量

我确实有这个正则表达式来匹配变量

/(?:char|int)\s*([A-z0-9]*)\s*=\s*"(.*)"/

然而,正则表达式也匹配块内的所有匹配项。

如何仅单独匹配前 2 个变量而忽略 bankLink 块内的所有变量?

【问题讨论】:

  • 什么实现? php? Javascript?

标签: regex


【解决方案1】:

这有点骇人听闻,但您可以尝试添加负前瞻,如下所示:

/(?:char|int)\s*([A-z0-9]*)\s*=\s*"(.*)"(?![^{]*\})/
                                        ^^^^^^^^^^^

这假设所有的大括号都是平衡的,幸运的是嵌套应该无关紧要(而在类似的问题中通常它会这样),因为您正在寻找 outside 括号的大小写。

前瞻基于以下观察:如果您遇到闭括号而没有遇到开括号,那么我们可以合理地假设我们在括号内。

人们很想以另一种方式扩展它以包含负面的查看后向,但不幸的是,大多数实现不支持可变长度的后向。

编辑:

正如下面的 cmets 中所讨论的,建议进行以下修复:

/(?:char|int)\s*([A-Za-z0-9]*)\s*=\s*"([^"]*)"(?![^{]*\})/
                    ^^^                ^^^^^

【讨论】:

  • +1,但我将 A-z 更改为 A-Za-z,因为 ASCII Z 和 ASCII a 之间有一些您不想匹配的非字母字符。跨度>
  • @TimPietzcker - 谢谢,蒂姆。我只是从他的问题中粘贴了正则表达式来向他展示不同之处,但这是一个很好的观点。我也会编辑他的问题。
  • 好主意。此外,"([^"]*)" 可能会比"(.*)" 更好,但由于似乎每行最多有一个键/值对,并且没有设置 dotall 模式,所以这不是一个大问题。
  • @TimPietzcker - 实际上,这是一个很好的观点。在偶然的dotall is 集合中,我认为.* 的贪婪会产生不需要的结果, 如果我们在大括号内,则匹配所有内容过去右括号,直到我们在外面然后应用(并匹配)负前瞻。我会进行编辑。我看到也可以进行其他改进,但与此相比,它们似乎很小。
  • @TimPietzcker - 以防您回头查看并感到困惑,我恢复了 A-Za-z 更改以显示与原始正则表达式的差异,然后在单独的编辑中提到了其他修复。
【解决方案2】:

看看这样的东西是否适合你:

^(?:char|int)[^\n\r]*?$

或者只是在你的表情前面放一个^

【讨论】:

    【解决方案3】:

    这可能不是最好的解决方案,但我认为这将适用于您的情况:

    /^(int|char).*$/
    

    原因是您的声明在 bankLine 块内缩进。这就是我们在这里所利用的。我们只是匹配所有以 int 或 char 开头且开头没有任何空格的行。

    【讨论】:

      猜你喜欢
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-03
      相关资源
      最近更新 更多