正则表达式匹配点,但不包括嵌套方括号

时间:2017-07-13 15:53:34

标签: javascript regex

输入

books.copies.[read_by.[p_id="65784"].page=5468].text.[paragraph="20"].letters

这个想法是用点分割字符串但忽略方括号内的那些

所以拆分后应该有一个数组

[
  'books',
  'copies',
  '[read_by.[p_id="65784"].page=5468]',
  'text',
  '[paragraph="20"]',
  'letters'
]

我已经查看了this answer,但它不能使用嵌套方括号,这就是我需要的。我也使用javascript,因此不支持负面的后视镜。

非常感谢帮助。

编辑1:展开示例

2 个答案:

答案 0 :(得分:1)

使用Javascript中的正则表达式无法匹配嵌套结构是不可能的。你需要使用好的旧方法:堆栈。



var text = 'books.copies.[read_by.[p_id="65784"].page=5468].text.[paragraph="20"].letters';

var item = '', result = [], stack = 0;

for (var i=0; i < text.length; i++) {
    if ( text[i] == '.' && stack == 0 ) {
        result.push(item);
        item = '';
        continue;
    } else if ( text[i] == '[' ) {
        stack++;
    } else if ( text[i] == ']' ) {
        stack--;
    }
    item += text[i];
}

result.push(item);

console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你需要为此编写解析器,因为JavaScript正则表达式不支持正则表达式递归,也不支持平衡结构。

这些函数的要点是它们保留了一个堆栈levelopenBrackets)的开头分隔符(在您的情况下,它是[)然后检查堆栈状态:如果堆栈不是emppty,则在括号内考虑找到的.,因此只是附加到当前匹配。否则,当堆栈为空时,.找到被认为是在括号之外,因此用于拆分(当前值附加到输出数组resultret ))。

&#13;
&#13;
function splitByDotsOutsideBrackets(string){
    var openBrackets = 0, ret = [], i = 0;
    while (i < string.length){
        if (string.charAt(i) == '[')
            openBrackets++;
        else if (string.charAt(i) == ']')
            openBrackets--;
        else if (string.charAt(i) == "." && openBrackets == 0){
            ret.push(string.substr(0, i));
            string = string.substr(i + 1);
            i = -1;
        }
        i++;
    }

    if (string != "") ret.push(string);
    return ret;
}
var res = splitByDotsOutsideBrackets('books.copies.[read_by.[p_id="65784"].page=5468].text.[paragraph="20"].letters');
console.log(res);
&#13;
&#13;
&#13;

或另一种变体:

&#13;
&#13;
function splitOnDotsOutsideNestedBrackets(str) {
    var result = [], start = 0, level = 0;
    for (var i = 0; i < str.length; ++i) {
        switch (str[i]) {
            case '[':
                ++level;
                break;
 
            case ']':
                if (level > 0)    
                    --level;
                break;
 
            case '.':
                if (level)
                    break;
                if (start < i)
                    result.push(str.substr(start, i - start));
                start = i + 1;
                break;
        }
    }
 
    if (start < i)
        result.push(str.substr(start, i - start));
   
    return result;
}

var s = 'books.copies.[read_by.[p_id="65784"].page=5468].text.[paragraph="20"].letters';
console.log(splitOnDotsOutsideNestedBrackets(s))
&#13;
&#13;
&#13;

改编自one of my previous answers