正则表达式通过单个字符串字符串拆分字符串,但识别括号和引号对

时间:2018-02-08 19:49:14

标签: javascript regex split

我正在寻找一种方法来将字符串拆分为特定字符但考虑到一些基本语法,本质上是检测匹配的括号和引号对并将它们视为一个单元。我不确定regexp是否可行,至少不是因为我的专业水平。

let str="a,pow(3,4),new Value({a:1,b:2}),'{this is a literal, all (this) is a \"single entity'";

let regexp=/what goes here?/;

let arr=str.split(regexp);

预期结果:

  • 一个
  • POW(3,4)
  • 新价值({a:1,b:2})
  • '{这是一个文字,所有(这个)是一个“单一实体”

我希望这不是重复,无法找到以前的回复

2 个答案:

答案 0 :(得分:4)

很遗憾,(*SKIP)(*FAIL)不支持JS,但您可以在某种程度上模仿它:

  1. 定义想要匹配的内容并将其置于交替中。
  2. 定义想要匹配的内容并将其放入捕获组
  3. 用sth替换组。在原始字符串中不会出现
  4. 按此顺序拆分。
  5. <小时/> 表达式

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

    ...和JavaScript代码:

    var subject = "a,pow(3,4),new Value({a:1,b:2}),'{this is a literal, all (this) is a \"single entity'";
    
    var regex = /\([^()]*\)|'[^']*'|(,)/g;
    
    replaced = subject.replace(regex, function(m, group1) {
        if (typeof group1 == 'undefined') return m;
        else return "SUPERMAN";
    });
    
    console.log(replaced.split(/SUPERMAN/));

    <小时/> 查看expression on regex101.com的演示并阅读@ctwheels'评论 - 上述代码段不适用于递归子模式。 你可以(不是说,你应该)在支持递归模式的另一种语言中使用递归方法,例如PCRE

    (?:(\((?:[^()]*|(?1))*\))|'[^']*')(*SKIP)(*FAIL)|,
    

    这也支持嵌套括号,请参阅a demo on regex101.com 否则,你需要在这里写一个小解析器。

答案 1 :(得分:2)

您正在对字符串进行标记,因此,您可以匹配1个或多个'...'(...)子字符串序列或除逗号以外的任何1个字符的块。

使用

/(?:'[^']*'|\([^()]*\)|[^,])+/g

这是regex demo

<强>详情

  • (?:'[^']*'|\([^()]*\)|[^,])+ - 1个或多个序列:
    • '[^']*' - 除''以外的',0 +个字符
    • | - 或
    • \([^()]*\) - (字符,除()以外的0 +字符,然后是)
    • | - 或
    • [^,] - ,
    • 以外的字符

参见JS演示:

&#13;
&#13;
let str="a,pow(3,4),new Value({a:1,b:2}),'{this is a literal, all (this) is a \"single entity'";
let rx = /(?:'[^']*'|\([^()]*\)|[^,])+/g;
console.log(str.match(rx));
&#13;
&#13;
&#13;

嵌套括号方法:

&#13;
&#13;
function splitIt(str) {
    var result = [], start = 0, level = 0, in_par = false, in_quotes = false;
    for (var i = 0; i < str.length; ++i) {
        switch (str[i]) {
            case '(':
                if (!in_quotes) ++level;
                break;
 
            case ')':
                if (level > 0 && !in_quotes)
                    --level;
                break;
            case "'":
                    in_quotes = !in_quotes;
                    break;
 
            case ',':
                if (level || in_quotes || in_par)
                    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 = "a,pow(3,(4,5)),new Value({a:1,b:2}),'{this is a literal, all (this) is a \"single entity'";
console.log(splitIt(s))
&#13;
&#13;
&#13;