Javascript Regex to split line by comma - javascript

I want a regex expression for javascript which should split the line by comma and should not split the expressions inside the brackets
Eg:
BuiltInFunctions.REPLACE_FIRST,Type.STRING, Type.STRING, 2, getArgTypeIns(Type.STRING, Type.STRING, Type.BOOLEAN)
to
BuiltInFunctions.REPLACE_FIRST
Type.STRING
Type.STRING
2
getArgTypeIns(Type.STRING, Type.STRING, Type.BOOLEAN)

This regex will split by commas, except those followed by brackets:
/,(?![^(]*\))/m
DEMO

Consider simplifying your operation:
var input = "BuildInFunctions...........";
var parentheses = [];
var replaced = input.replace(/\(.*?\)/g,function(m) {
parentheses.push(m);
return "{{PARENS:"+(parentheses.length-1)+"}}";
});
var parts = replaced.split(",");
var result = parts.map(function(part) {
return part.replace(/\{\{PARENS:(\d+)\}\}/g,function(_,i) {return parentheses[i];});
});
The general idea is to extract all parenthesised expressions, then process the split, then put the parenthesised stuff back in. Much easier than trying to do it in one step with a regex (which I'm not sure is possible, to be honest)

Related

Regex for matching only first of two same characters in a string

I have these two strings: "1-2" and "1--2".
I would like to have a regex that would match only the first occurrence of the hyphen in both strings, such that the split would then be: [1,2] and [1,-2]. How would I achieve this, since I have been wracking my brain for too long on this now?
EDIT: The two strings can also occur in the same string such that: "1-2-1--2". Therefore a single regular expression covering both cases would be in order.
You can use this split with a word boundary before -:
let s='1-2-1--2'
let arr = s.split(/\b-/)
console.log(arr)
//=> [1, 2, 1, -2)
You can use simple split(), but with replacement. For example,
var str = '1-2-1--2';
var numArr = str.replace(/--/g, '-~') // The tilde (~) have no mean, this is a charceter for mark a negative number
.split('-')
.map(function(n) { return Number(n.replace('~', '-')); });
console.log(numArr);
I think you're looking for something like this:
(-?[0-9]+)-(-?[0-9]+)
where the first and the second group could have a negative sign
UPDATE:
based on your edit, this implementation would do the job:
var str = '-1--2-2--34-1';
var regex = /(-?\d+)-?/g;
var matches = [];
while((match = regex.exec(str))) {
matches.push(match[1]);
}
console.log(matches);
I prefer using split, but it's fine if you only want to use RegEx.

Convert string with index in brackets to JSON array

I have various strings with numbers in brackets like "[4]Motherboard, [25]RAM" how can I convert such a string to a JSON array (keeping both ids and values) like this:
{"data":[
{"id":"4","item":"Motherboard"},
{"id":"25","item":"RAM"}
]};
I'm tried using split(",") to create the array but I really can't find out how to get the inner data in this case.
You could use a regular expression, which takes the number and the string, and assign it as property to an object.
var string = "[4]Motherboard, [25]RAM",
data = string.split(', ').map(function (a) {
var p = a.match(/^\[(\d+)\](.+)$/);
return { id: p[1], item: p[2] };
});
console.log(data);
Here one way to do it. The pattern \[(\d+?)\](.+) works like this:
(…) is a capture group. Just means whatever matches within the brackets will be a token in the result.
\d means a digit
\d+ means a digit, one or more times
\d+? means a digit, one or more times, but as few as possibile before the pattern matches something else.
.+ means any character, one or more times.
[ and ] have a special meaning in regular expression, so if you actually want to match the characters themselves, you need to escape them like so \[ and \].
The double backslashes \\ are just a JS oddity when defining a regex via a string as opposed to using a /literal/. Just two ways of saying the same thing.
There's plenty of resources to learn regex syntax, and http://regex101.com is a great place to play with patterns and experiment.
var input = "[4]Motherboard, [25]RAM";
var pattern = '\\[(\\d+?)\\](.+)';
var result = input.split(',').map(function (item) {
var matches = item.match(new RegExp(pattern));
return {id: matches[1], val: matches[2]};
});
console.log(result)
function toArray(string) {
return {
data: string.split(",").map(function(str) {
str = str.trim();
return {
id: str.substring(1, str.indexOf("]")),
item: str.substring(str.indexOf("]") + 1),
};
}),
};
}

Regexp, capture between parentheses, javascript

I have regexp that extracts values between parentheses.
It's working most of the time but not when it ends with a parentheses
var val = 'STR("ABC(t)")';
var regExp = /\(([^)]+)\)/;.
var matches = regExp.exec(val);
​
console.log(matches[1]); //"ABC(t"
What I want is "ABC(t)".
Any ideas how I can modify my regexp to Achive this?
Update
The value is always inside the parentheses.
Some examples:
'ASD("123")'; => '123'
'ASD(123)'; => '123'
'ASD(aa(10)asda(459))'; => 'aa(10)asda(459)'
So first there is some text (always text). Then there is a (, and it always ends with a ). I want the value between.
You may use greedy dot matching inside Group 1 pattern: /\((.+)\)/. It will match the first (, then any 1+ chars other than linebreak symbols and then the last ) in the line.
var vals = ['STR("ABC(t)")', 'ASD("123")', 'ASD(123)', 'ASD(aa(10)asda(459))'];
var regExp = /\((.+)\)/;
for (var val of vals) {
var matches = regExp.exec(val);
console.log(val, "=>", matches[1]);
}
Answering the comment: If the texts to extract must be inside nested balanced parentheses, either a small parsing code, or XRegExp#matchRecursive can help. Since there are lots of parsing codes around on SO, I will provide XRegExp example:
var str = 'some text (num(10a ) ss) STR("ABC(t)")';
var res = XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/2.0.0/xregexp-all-min.js"></script>

Modify formatting-pattern to replace placeholders in string

I write currently a simple formatting function to replace some placeholders in a string.
var format = function (a, c) {
return a.replace(/{ *([^} ]+) *}/g, function (b, a) {
b = c;
a.replace(/[^.|\[\]]+/g, function (a) {
b = b[a];
});
return b;
});
};
The syntax uses currently curly-bracket notation {key}, I try now to modify the RegExp-pattern to work with one percent instead %key.
var pattern = /{ *([^} ]+) *}/g;
I tried to just replace the parentheses {} with a percent %, but this still doesn't work properly.
var pattern = /% *([^% ]+) */g;
The original pattern works with the following conditions as expected:
var data = {
obj: {
foo: 'Foo',
bar: 'Bar'
},
arr: ['Foo', 'Bar']
};
var objTest = '{obj.foo}, is not equal to {obj.bar}.'
format(objTest, data) // => 'Foo, is not equal to Bar.'
var arrTest = '{arr[0]}, is not equal to {arr[1]}.'
format(arrTest, data) // => 'Foo, is not equal to Bar.'
If we use my modified pattern it seems that the last character after each placeholder-replacement will be removed:
'%obj.foo, is not equal to %obj.bar.' // => 'undefined is not equal to Bar'
'%arr[0], is not equal to %arr[1]' // => 'undefined is not equal to Bar'
Any ideas how to modify the pattern to make it possible to use it with percentage % instead of curly-brackets {}?
You can use this pattern:
var regex = /%([^\b]+)/g;
which means a % sign followed by a complete word. This excludes whitespace characters, underscores, etc.
If you instead want to be able to use those characters as well, you can write:
var regex = /%(\S+)/g;
which is the equivalent of:
var regex = /%([^\s]+)/g;
The reason for this is that your modified regex pattern does not know when to stop matching. In the previous one it terminated at the following } symbol.
This is not an easy thing to fix as there is a myriad of possibilities that could be seen to end your format, here you have a piece of punctuation at the end of each replacement string, i.e. a full stop %arr[1]. or comma %obj.foo,.
So to make this work in your case toy could replace } in the original pattern with [\.,] i.e.
/% *([^% ]+) *[\.,]/g
This will work, but now your replacement pattern needs to always be terminated with either a full stop or comma which i suspect is not exactly what you want. Better to terminate with a know character such as % which would make your matching pattern /% *([^% ]+) *%/g and your format %obj.foo% and you can output a % by doubling up i.e. %obj.bar%%%

Javascript split function not correct worked with specific regex

I have a problem. I have a string - "\,str\,i,ing" and i need to split by comma before which not have slash. For my string - ["\,str\,i", "ing"]. I'm use next regex
myString.split("[^\],", 2)
but it's doesn't worked.
Well, this is ridiculous to avoid the lack of lookbehind but seems to get the correct result.
"\\,str\\,i,ing".split('').reverse().join('').split(/,(?=[^\\])/).map(function(a){
return a.split('').reverse().join('');
}).reverse();
//=> ["\,str\,i", "ing"]
Not sure about your expected output but you are specifying string not a regex, use:
var arr = "\,str\,i,ing".split(/[^\\],/, 2);
console.log(arr);
To split using regex, wrap your regex in /..../
This is not easily possible with js, because it does not support lookbehind. Even if you'd use a real regex, it would eat the last character:
> "xyz\\,xyz,xyz".split(/[^\\],/, 2)
["xyz\\,xy", "xyz"]
If you don't want the z to be eaten, I'd suggest:
var str = "....";
return str.split(",").reduce(function(res, part) {
var l = res.length;
if (l && res[l-1].substr(-1) == "\\" || l<2)
// ^ ^^ ^
// not the first was escaped limit
res[l-1] += ","+part;
else
res.push(part);
return;
}, []);
Reading between the lines, it looks like you want to split a string by , characters that are not preceded by \ characters.
It would be really great if JavaScript had a regular expression lookbehind (and negative lookbehind) pattern, but unfortunately it does not. What it does have is a lookahead ((?=) )and negative lookahead ((?!)) pattern. Make sure to review the documentation.
You can use these as a lookbehind if you reverse the string:
var str,
reverseStr,
arr,
reverseArr;
//don't forget to escape your backslashes
str = '\\,str\\,i,ing';
//reverse your string
reverseStr = str.split('').reverse().join('');
//split the array on `,`s that aren't followed by `\`
reverseArr = reverseStr.split(/,(?!\\)/);
//reverse the reversed array, and reverse each string in the array
arr = reverseArr.reverse().map(function (val) {
return val.split('').reverse().join('');
});
You picked a tough character to match- a forward slash preceding a comma is apt to disappear while you pass it around in a string, since '\,'==','...
var s= 'My dog, the one with two \\, blue \\,eyes, is asleep.';
var a= [], M, rx=/(\\?),/g;
while((M= rx.exec(s))!= null){
if(M[1]) continue;
a.push(s.substring(0, rx.lastIndex-1));
s= s.substring(rx.lastIndex);
rx.lastIndex= 0;
};
a.push(s);
/* returned value: (Array)
My dog
the one with two \, blue \,eyes
is asleep.
*/
Find something which will not be present in your original string, say "###". Replace "\\," with it. Split the resulting string by ",". Replace "###" back with "\\,".
Something like this:
<script type="text/javascript">
var s1 = "\\,str\\,i,ing";
var s2 = s1.replace(/\\,/g,"###");
console.log(s2);
var s3 = s2.split(",");
for (var i=0;i<s3.length;i++)
{
s3[i] = s3[i].replace(/###/g,"\\,");
}
console.log(s3);
</script>
See JSFiddle

Categories