regexp incorreclty split:用逗号但不在括号内(两者)和])

时间:2018-01-17 10:45:21

标签: javascript regex

正则表达式的想法:用逗号分隔,后面没有任何字符和)或]。 此外,应该考虑两个括号(和[。假设:字符串包含有效括号。

这是我的功能:

function spl(str) {
    var reg = /\,(?!(?:[\w|\s]*\,?)*[\)\]])/;  
    console.log(str.split(reg));
}

问题:

incorrectly: spl("tpr(7,4%), nitrita sals (sals- 1.2%, konservants E250)");
incorrectly: spl("tpr(7,4%), nitri(a,b,c[a,b])ta sals (sals- 1.2%, konservants E250),fsfs");
incorrectly: if there are brackets within brackets

以下是示例:

 str = "a,b (c,d,e)";
// expected: split into strings "a", "b (c,d,e)"

 str = "a,b [c,d,e]";
 // expected: split into strings "a", "b [c,d,e]"    

 str = "tpr(7,4%), nitrita sals (sals- 1.2%, konservants E250)";
 // expected split into "tpr(7,4%)", "nitrita sals (sals- 1.2%, konservants E250)"

 str = "tpr(7,4%), nitri(a,b,c[a,b])ta sals (sals- 1.2%, konservants E250),fsfs";
 //expected: "tpr(7,4%)", "nitri(a,b,c[a,b])ta sals (sals- 1.2%, konservants E250)" and "fsfs"

  str = "šokolāde 47% (cukurs, kakao sviests, (SOJAS); vanilīns), pulv";
  // expected: splited into two strings; "šokolāde 47% (cukurs, kakao sviests, (SOJAS); vanilīns)" and "pulv"

2 个答案:

答案 0 :(得分:2)

您可以在此正则表达式中使用否定前瞻断言:

/,\s*(?![^()]*\)|[^\]\[]*\])/

RegEx Demo

  • \s*,\s*:匹配逗号,两边有0个或更多个空格
  • (?![^()]*\)|[^\]\[]*\]):是一个负向前瞻性表达式,断言我们前面没有)跟随0个或更多个非圆括号字符或没有]前面跟着0个或更多非方括号字符。

PS:请注意,此正则表达式解决方案仅适用于非嵌套和非转义括号。要处理相同类型的嵌套括号,请使用解析器代码,如下所示。

var arr = ['a,b (c,d,e)', 'a,b [c,d,e]',
'tpr(7,4%), nitrita sals (sals- 1.2%, konservants E250)',
'tpr(7,4%), nitri(a,b,c[a,b])ta sals (sals- 1.2%, konservants E250),fsfs',
'šokolāde 47% (cukurs, kakao sviests, (SOJAS); vanilīns), pulv'];

for (var j=0, arrlen=arr.length; j < arrlen; j++)
  console.log("*** Pocessing:", arr[j], "=>", splitComma(arr[j]));

function splitComma(str) {
  var result = [];
  var lvl = {'rb':0, 'sb':0};
  var tmp = '';
  var cd = 0;
  
  for (var i = 0, len = str.length; i < len; i++) {
    var ch = str.charAt(i);
    
    if (ch == '(')
      lvl['rb']++;
    else if (ch == '[')
      lvl['sb']++;

    if (lvl['rb'] + lvl['sb'] == 0 && ch == ',') {
      result.push(tmp.trim());
      tmp = '';
    }
    else
      tmp += ch;
      
    if (ch == ')')
      lvl['rb']--;
    else if (ch == ']')
      lvl['sb']--;
  }      
  result.push(tmp.trim());
  return(result);
}

答案 1 :(得分:1)

如果你需要处理嵌套,你需要在处理之前解析,单凭regex不会为你处理它。这不是世界上最好的解析器,但它不是我的头脑,而是你可以用来处理这个问题的一个例子。或者只是找到一个旨在处理这种用例的解析器

var test = "m,oo (ba,a) mbo,ool [sdf,lkj (sdfl,kj)] sd,fjk"
            
            function groupStr(str, exclusionPairs){
                let charArr = str.split(''),
                    exclusionLookup = exclusionPairs.reduce((obj, pair) => { obj[pair[0]] = pair[1]; return obj }, {}),
                    arrayOfPieces = [],
                    pieceArray = [],
                    flaggedExclusion = null,
                    char
                
                while((char = charArr.shift()) !== undefined){
                    if(flaggedExclusion){
                        pieceArray.push(char)
                        if(char == flaggedExclusion){
                            arrayOfPieces.push({
                                str: pieceArray.join(""),
                                exclude: true
                            })
                            pieceArray = []
                            flaggedExclusion = null
                        }
                    } else if(exclusionLookup[char]){
                        if(pieceArray.length){
                            arrayOfPieces.push({
                                str: pieceArray.join(""),
                                exclude: false
                            })
                            pieceArray = []
                        }
                        pieceArray.push(char)
                        flaggedExclusion = exclusionLookup[char]
                    } else {
                        pieceArray.push(char)
                    }
                }
                
                if(pieceArray.length){
                    arrayOfPieces.push({
                        str: pieceArray.join(""),
                        exclude: false
                    })
                }
                
                console.log(arrayOfPieces)
                
                return arrayOfPieces
            }
            
            let result = groupStr(test, [
                ["(",")"],
                ["[","]"]
            ])
            
            
            let splitArray = result.reduce((arr, piece) => {
                if(piece.exclude) arr.push(piece.str)
                else arr = arr.concat(piece.str.split(","))
                
                return arr
            }, [])
            
            console.log(splitArray)