正则表达式,以查找是否只有一个代码块

时间:2014-07-25 12:08:36

标签: javascript regex

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

示例:

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

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

语言是JavaScript。

4 个答案:

答案 0 :(得分:4)

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

简而言之:在JavaScript中我无法想到可靠的解决方案。在其他引擎中有几种选择:

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

对于解决方案2(无论如何也无法在JS中工作),我将引用您this question

中的示例

递归正则表达式

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

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

这个想法是恰好匹配一组嵌套大括号。任何更多的东西使正则表达式失败。

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

<强>解释

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

答案 1 :(得分:1)

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

由于这是在Javascript中没有太多事情要做,但请看下面的正则表达式:

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

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

Online Regex Demo

答案 2 :(得分:0)

在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提出要求后首先删除评论,字符串和正则表达式文字中的任何内容。

答案 3 :(得分:-1)

(\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*

括号代码