I have a string that I want to split into an array by using the commas as delimiters. I do not want the portions of the string that is between parentheses to be split thoug
var regex = /,(?![^(]*\)) /;
var str = "bibendum, morbi, non, quam (nec, dui, luctus), rutrum, nulla";
var splitString = str.split(regex);
Here you go. An explanation of the regex:
, //Match a comma
(?! //Negative look-ahead. We want to match a comma NOT followed by...
[^(]* //Any number of characters NOT '(', zero or more times
/) //Followed by the ')' character
) //Close the lookahead.
I don't like to have large opaque regular expressions in my code so I used a different solution. It still makes use of regex but I think is somewhat more transparent.
I use a simpler regex to replace any commas within parenthesis with a special string. I then split the string by commas, then within each resulting token I replace the special string with a comma.
splitIgnoreParens(str: string): string[]{
const SPECIAL_STRING = '$REPLACE_ME';
// Replaces a comma with the special string
const replaceComma = s => s.replace(',',SPECIAL_STRING);
// Vice versa
const replaceSpecialString = s => s.replace(SPECIAL_STRING,',');
// Selects any text within parenthesis
const parenthesisRegex = /\(.*\)/gi;
// Withing all parenthesis, replace comma with special string.
const cleanStr = str.replace(parenthesisRegex, replaceComma);
const tokens = cleanStr.split(',');
const cleanTokens = tokens.map(replaceSpecialString);
return cleanTokens;
}
var start = "bibendum, morbi, non, quam (nec, dui, luctus), rutrum, nulla";
start = start.replace(/ /g,'');
console.log(start);
var front = start.substring(0,start.lastIndexOf('(')).split(',');
var middle = '('+start.substring(start.lastIndexOf('(')+1,start.lastIndexOf(')'))+')';
var end = start.substring(start.lastIndexOf(')')+2,start.length).split(',');
console.log(front)
console.log(middle)
console.log(end)
return front.concat(middle,end);
You don't need fancy regular expressions for this.
s="bibendum, morbi, non, quam (nec, dui, luctus), rutrum, nulla"
var current='';
var parenthesis=0;
for(var i=0, l=s.length; i<l; i++){
if(s[i] == '('){
parenthesis++;
current=current+'(';
}else if(s[i]==')' && parenthesis > 0){
parenthesis--;
current=current+')';
}else if(s[i] ===',' && parenthesis == 0){
console.log(current);current=''
}else{
current=current+s[i];
}
}
if(current !== ''){
console.log(current);
}
Change console.log for an array concatenation or what ever you want.
Instead of focusing on what you do not want it's often easier to express as a regular expression what you want, and to match that with a global regex:
var str = "bibendum, morbi, non, quam (nec, dui, luctus), rutrum, nulla";
str.match(/[^,]+(?:\(+*?\))?/g) // the simple one
str.match(/[^,\s]+(?:\s+\([^)]*\))?/g) // not matching whitespaces