我的输入是一个字符串,我想验证只有一个第一级代码块。
示例:
{ abc } TRUE
{ a { bc } } TRUE
{ a {{}} } TRUE
{ abc {efg}{hij}} TRUE
{ a b cde }{aa} FALSE
/^\{.*\}$/
对5个案例有效,你能帮我找到最后一个案例的正则表达式无效吗?
语言是JavaScript。
答案 0 :(得分:4)
编辑:我在指定JavaScript之前开始编写答案。将其留作记录,因为它完全解释了正则表达式。
简而言之:在JavaScript中我无法想到可靠的解决方案。在其他引擎中有几种选择:
对于解决方案2(无论如何也无法在JS中工作),我将引用您this question
中的示例在Perl,PCRE(例如Notepad ++,PHP,R)和Matthew Barnett的Python regex
模块中,您可以使用:
^({(?:[^{}]++|(?1))*})$
这个想法是恰好匹配一组嵌套大括号。任何更多的东西使正则表达式失败。
在 the Regex Demo 中查看匹配和失败的内容。
<强>解释强>
^
锚点断言我们位于字符串的开头{
匹配左大括号(?: ... )*
零次或多次,我们会...... [^{}]++
匹配任何非{
或}
|
(?1)
重复子程序1的表达}
匹配右括号$
锚点断言我们位于字符串的末尾。因此,答案 1 :(得分:1)
由于这是在Javascript中没有太多事情要做,但请看下面的正则表达式:
/^{([^{}]*|{})*}$/
复制([^{}]*|{})*
并将其插入最后一对花括号(冲洗和重复)之间。这种模式的每次重复都允许在元素之间进行另一层嵌套。 (这是解决嵌套问题所需的JS regex中缺少递归的一种解决方法。)
答案 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)
(\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*|\(([^()]*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*\))*
括号代码