【问题标题】:Regex to find if there is only one block of code正则表达式查找是否只有一个代码块
【发布时间】:2014-09-17 07:02:00
【问题描述】:

我的输入是一个字符串,我想验证只有一个 一级 代码块。

例子:

{ abc }              TRUE
{ a { bc } }         TRUE
{ a {{}} }           TRUE
{ abc {efg}{hij}}    TRUE
{ a b cde }{aa}      FALSE

/^\{.*\}$/ 对 5 种情况有效,你能帮我找到一个对最后一种情况无效的正则表达式吗?

语言是 JavaScript。

【问题讨论】:

  • 什么正则表达式风格,或者什么语言?
  • 使用前瞻而不是查看字符串 (?={) 的末尾。如果前瞻计算结果为真,则您的正则表达式不匹配。
  • 传统正则表达式无法处理嵌套结构。现代正则表达式解析器更好,但处理嵌套结构仍然不完美。
  • 是否存在“}{”可以存在的有效(TRUE)情况?
  • 总有选择,DIY

标签: javascript regex


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

括号代码

【讨论】:

  • 没有解释,长时间重复的正则表达式处理的是常规括号而不是大括号。
  • 用于验证括号()()-有效())-无效()()())-无效
【解决方案2】:

在 JavaScript 中,你需要做的是去掉所有嵌套的块,直到没有 嵌套 块,然后检查是否还有多个块:

var r = input.replace(/(['"])(?:(?!\1|\\).|\\.)*\1|\/(?![*/])(?:[^\\/]|\\.)+\/[igm]*|\/\/[^\n]*(?:\n|$)|\/\*(?:[^*]|\*(?!\/))*\*\//gi, '');

if (r.split('{').length != r.split('}').length || r.indexOf('}') < r.indexOf('{')) {
    // ERROR
    continue;
}

while (r.match(/\{[^}]*\{[^{}]*\}/))
    r = r.replace(/(\{[^}]*)\{[^{}]*\}/g, '$1');
if (r.match(/\}.*\{/)
    // FALSE
else
    // TRUE

工作JSFiddle

确保while 中的正则表达式和replace 中的正则表达式匹配相同,否则可能导致无限循环。

更新以解决错误情况,并在 Unihedron 询问后首先删除 cmets、字符串和正则表达式中的任何内容。

【讨论】:

  • 会返回 TRUE,但它是一个“不正确”的代码块。如果您想检查不匹配的开放花括号,这是一个不同的问题,尽管确实相关。但是你会想考虑像{ print "Went there {" } /* } { Dang edge cases! } */ 这样的东西。我在这里写过这样的场景:stackoverflow.com/questions/25402109/…
【解决方案3】:

编辑:我在指定 JavaScript 之前就开始写答案了。将其保留为记录,因为它完全解释了正则表达式。

简而言之: 在 JavaScript 中,我想不出一个可靠的解决方案。在其他引擎中有几个选项:

  • 递归(我将在下面展开)
  • 平衡组 (.NET)

对于解决方案 2(无论如何也不会在 JS 中工作),我将向您推荐 this question 中的示例

递归正则表达式

在 Perl、PCRE(例如 Notepad++、PHP、R)和 Matthew Barnett 的 regex Python 模块中,您可以使用:

^({(?:[^{}]++|(?1))*})$

这个想法是精确匹配一组嵌套的大括号。任何更多都会使正则表达式失败。

查看 the Regex Demo 中的匹配项和失败项。

说明

  • ^ 锚断言我们位于字符串的开头
  • 外圆括号定义第 1 组(或子例程 1)
  • { 匹配左大括号
  • (?: ... )* 零次或多次,我们将...
  • [^{}]++ 匹配任何不是{} 的字符
  • |
  • (?1)重复子程序1的表达式
  • } 匹配右大括号
  • $ 锚断言我们位于字符串的末尾。因此,

【讨论】:

  • 不幸的是,OP 现在已指定他们正在寻找 javascript,并且此解决方案在 javascript 中无效。不过,对于递归正则表达式演示 +1。
【解决方案4】:

这是一个糟糕的解决方法。

由于这是在 Javascript 中,所以没有太多可做的,但请参阅以下正则表达式:

/^{([^{}]*|{})*}$/

复制([^{}]*|{})* 并将其插入到最后一对大括号之间(冲洗并重复)。这种模式的每一次重复都允许在你的元素之间进行另一层嵌套。 (这是解决嵌套问题所需的 JS 正则表达式中缺少递归的解决方法。)

Online Regex Demo

【讨论】:

  • 非常实用,对于复制粘贴正则表达式 +1,这可能适用于嵌套有限的实际情况。 :)
猜你喜欢
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多