【问题标题】:Regex match parenthesis that are not within square braces正则表达式匹配不在方括号内的括号
【发布时间】:2013-09-04 18:01:14
【问题描述】:

我正在尝试使用包含括号 (...) 的表达式来确定,其中 (...) 在方括号内不是。这用于解析和处理一些简单的 lisp 样式表达式。

我已经调整了以下 working 表达式,用于在不在方括号内的空格字符上拆分字符串,但对于上述情况,我似乎无法达到相同的效果.

我正在使用的表达式:

/(\[.*?\]|(\(.*\)+))/g

这里是一个示例表达式列表,其中包含所需的 hasPair 函数输出。

 - (+ 2 2) -> true
 - (+ 2 (- 4 2)) -> true
 - [(+ 2 2)] -> false 
 - [(def i (+ 2 2)] -> false
 - (defn add [+ 2 2]) -> true
 - def add [(+ 2 2)] -> false
 - (defn add x y [(+ x y]) -> true

我可能遗漏了一些明显的东西,但我看不出它是什么。

(如果有区别,表达式将始终保持平衡)

【问题讨论】:

  • 尝试提供更多示例,因为您的示例太简单了。
  • 要添加到@Juno 的评论中,您能否添加一个您将使用的真实文本的示例,以及结果匹配应该是什么?方括号总是紧挨着括号吗?
  • 可能是^\[\(.+\)^\]
  • @konopko 似乎与“(你好)”不匹配。 Juno & Matletics,编辑即将到来。
  • 你是对的,那是新的:\"^\[?\(.+\)^\]?\"

标签: javascript regex


【解决方案1】:
(?:[^[]|^)\(([\w]*)\)(?!\])

Edit live on Debuggex

不太确定你在找什么,但这就是它的样子!

新编辑:

(?:[^[]|^)?\((.*)\)(?!\])

Edit live on Debuggex

编辑 3:

(?:[^[]|^)\((.*?)\)(?:(?!\]))

Edit live on Debuggex

【讨论】:

  • 您确定需要|^ 吗?看起来它允许在那里使用文字 ^。
  • @ajp15243 是的,它仍然是“字符串的开头”。虽然我不能确定这是否适用于 the cases 我弥补了。
  • @Jerry 这正是我要指出的。看起来 Debuggex(在这些链接中使用 JavaScript 正则表达式)将表达式的|^ 部分中的^ 视为文字^,而不是“字符串开头”元字符。我希望这种行为,因为我希望| 元字符会导致其右侧的字符被视为文字,以实现| 的“OR”目的。但是,我不确定这是否是 progenhard 的预期行为。我怀疑他们试图说“或字符串开头”,这不是那个正则表达式似乎在做的事情。
  • @ajp15243 它的工作原理是它要么是 A) 一个不是 [ B) 字符串的开头,它将有没有字符的情况
  • @progenhard 您的正则表达式仍然有效,因为您有一个案例 C)A 和 B 都不是,因为您的 ? 在您的第一个非捕获模式分隔符的右侧((?:[^]]|^) 部分)这表示[^[] 和^ 分支是可选的。 Debuggex 图清楚地表明了这一点。因此,您可以直接进入第一个 ( 字符之前没有任何内容(案例 C),在 ( 之前匹配单个非 [ 字符(案例 A),或者在之前匹配单个文字 ^第一个((案例B,您断言它是字符串开头的元字符)。这就是图表向我展示的内容。
【解决方案2】:

也许你可以试试这个:

\([^\)]+\)(?![^\[]*\])

regex101 demo

这只有在方括号(我认为还有括号)是平衡的情况下才有效。

编辑:好的,现在这是一个疯狂的正则表达式 xD

\((?:[^\)\[\]]+|(?:[^\[\]\)]*\[[^\[\]\)]*\][^\[\]\)]*))*\)(?![^\[]*\])

regex101 retry

【讨论】:

  • [(...]) 很可能不是一个有效的用例,因此您可能不必关心那个特殊情况。
  • @ajp15243 是的,我后来才看到编辑。我稍微改变了正则表达式......? xD Itr 确实令人困惑,尽管对于 [ 和 ] 的所有否定类。
  • @Jerry 打错了,现已修正。
  • @DanPrince 这可以防止) 后跟](即在方括号内)但如果) 后跟[ ] 则不会。这更清楚还是我应该在答案中添加一段以获得更多详细信息? :)
  • @Jerry:明白了,谢谢。我输入了一个不起作用的输入,更新了示例。
【解决方案3】:

正则表达式只是众多工具之一,最适合某些任务 - 这不是其中之一。

如果这对总是平衡的,那么您真正需要的只是知道天气是否在任何给定字符串中的左括号之前。

这很容易通过评估以下来实现

str.indexOf('[') < str.indexOf('(')

【讨论】:

  • 我应该更清楚一点,如果我只是验证,这可以工作,但最终我正在处理大括号之间的表达式,这样做是因为正则表达式匹配会立即返回,而不是必须验证字符串,然后找到第一个和最后一个括号的索引以创建适当的子字符串。
  • 实际上 indexOf,即使在多行上完成,也可能比满足您需求的正则表达式快几个数量级。问题是代码密度对您来说是否比性能和易于维护更重要。 indexOf/substr 路线是 2-3 行代码而不是 1 行,但在这种情况下更喜欢 imo。我喜欢强大的正则表达式,并且一直使用它们,但有时技能是知道,而不是使用它们;)
【解决方案4】:

我建议在这里保持简单。考虑下面的代码:

/\([^)]*\)/.test(str.replace(/\[[^\]]*\]/g, ''));

分两步解决此任务:

  1. 第一阶段:用空字符串""替换所有[...]匹配。
  2. 第二阶段:检查(...)是否仍然存在于被替换的字符串中。

Working Demo: http://ideone.com/aVu9iR

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    相关资源
    最近更新 更多