Got this type of string:
var myString = '23, 13, (#752, #141), $, ASD, (#113, #146)';
I need to split it to an array with comma as separator but also converts (..) to an array.
This is the result I want: [23, 13, ['#752', '#141'], '$', 'ASD', ['#113', '#146']];
I got huge data-sets so its very important to make it as fast as possible. What's the fastest way? Do some trick RegExp function or do it manually with finding indexes etc.?
Here's a jsbin: https://jsbin.com/cilakewecu/edit?js,console
Convert the parens to brackets, quote the strings, then use JSON.parse:
JSON.parse('[' +
str.
replace(/\(/g, '[').
replace(/\)/g, ']').
replace(/#\d+|\w+/g, function(m) { return isNaN(m) ? '"' + m + '"' : m; })
+ ']')
> [23,13,["#752","#141"],"ASD",["#113","#146"]]
You can use RegEx
/\(([^()]+)\)|([^,()\s]+)/g
RegEx Explanation:
The RegEx contain two parts. First, to capture anything that is inside the parenthesis. Second, capture simple values (string, numbers)
\(([^()]+)\): Match anything that is inside the parenthesis.
\(: Match ( literal.
([^()]+): Match anything except ( and ) one or more number of times and add the matches in the first captured group.
\): Match ) literal.
|: OR condition in RegEx
([^,()\s]+): Match any character except , (comma), parenthesis ( and ) and space one or more number of times and add the match in the second captured group
Demo:
var myString = '23, 13, (#752, #141), ASD, (#113, #146)',
arr = [],
regex = /\(([^()]+)\)|([^,()\s]+)/g;
// While the string satisfies regex
while(match = regex.exec(myString)) {
// Check if the match is parenthesised string
// then
// split the string inside those parenthesis by comma and push it in array
// otherwise
// simply add the string in the array
arr.push(match[1] ? match[1].split(/\s*,\s*/) : match[2]);
}
console.log(arr);
document.body.innerHTML = '<pre>' + JSON.stringify(arr, 0, 4) + '</pre>'; // For demo purpose only
Just use the split method.
var str = '23, 13, (#752, #141), ASD, (#113, #146)',
newstr = str.replace(/\(/gi,'[').replace(/\)/gi,']'),
splitstr = newstr.split(',');
Related
I need to parse a string that comes like this:
-38419-indices-foo-7119-attributes-10073-bar
Where there are numbers followed by one or more words all joined by dashes. I need to get this:
[
0 => '38419-indices-foo',
1 => '7119-attributes',
2 => '10073-bar',
]
I had thought of attempting to replace only the dash before a number with a : and then using .split(':') - how would I do this? I don't want to replace the other dashes.
Imo, the pattern is straight-forward:
\d+\D+
To even get rid of the trailing -, you could go for
(\d+\D+)(?:-|$)
Or
\d+(?:(?!-\d|$).)+
You can see it here:
var myString = "-38419-indices-foo-7119-attributes-10073-bar";
var myRegexp = /(\d+\D+)(?:-|$)/g;
var result = [];
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
result.push(match[1]);
match = myRegexp.exec(myString);
}
console.log(result);
// alternative 2
let alternative_results = myString.match(/\d+(?:(?!-\d|$).)+/g);
console.log(alternative_results);
Or a demo on regex101.com.
Logic
lazy matching using quantifier .*?
Regex
.*?((\d+)\D*)(?!-)
https://regex101.com/r/WeTzF0/1
Test string
-38419-indices-foo-7119-attributes-10073-bar-333333-dfdfdfdf-dfdfdfdf-dfdfdfdfdfdf-123232323-dfsdfsfsdfdf
Matches
Further steps
You need to split from the matches and insert into your desired array.
I have a long string
Full_str1 = 'ab#xyz.com;cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;c_ab#xyz.com;';
removable_str2 = 'ab#xyz.com;';
I need to have a replaced string which will have
resultant Final string should look like,
cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;c_ab#xyz.com;
I tried with
str3 = Full_str1.replace(new RegExp('(^|\\b)' +removable_str2, 'g'),"");
but it resulted in
cab#xyz.com;c-c.c_ab#xyz.com;
Here a soluce using two separated regex for each case :
the str to remove is at the start of the string
the str to remove is inside or at the end of the string
PS :
I couldn't perform it in one regex, because it would remove an extra ; in case of matching the string to remove inside of the global string.
const originalStr = 'ab#xyz.com;cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;ab#xyz.com;c_ab#xyz.com;';
const toRemove = 'ab#xyz.com;';
const epuredStr = originalStr
.replace(new RegExp(`^${toRemove}`, 'g'), '')
.replace(new RegExp(`;${toRemove}`, 'g'), ';');
console.log(epuredStr);
First, the dynamic part must be escaped, else, . will match any char but a line break char, and will match ab#xyz§com;, too.
Next, you need to match this only at the start of the string or after ;. So, you may use
var Full_str1 = 'ab#xyz.com;cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;c_ab#xyz.com;';
var removable_str2 = 'ab#xyz.com;';
var rx = new RegExp("(^|;)" + removable_str2.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "g");
console.log(Full_str1.replace(rx, "$1"));
// => cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;c_ab#xyz.com;
Replace "g" with "gi" for case insensitive matching.
See the regex demo. Note that (^|;) matches and captures into Group 1 start of string location (empty string) or ; and $1 in the replacement pattern restores this char in the result.
NOTE: If the pattern is known beforehand and you only want to handle ab#xyz.com; pattern, use a regex literal without escaping, Full_str1.replace(/(^|;)ab#xyz\.com;/g, "$1").
i don't find any particular description why you haven't tried like this it will give you desired result cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;c_ab#xyz.com;
const full_str1 = 'ab#xyz.com;cab#xyz.com;c-ab#xyz.com;c.ab#xyz.com;c_ab#xyz.com;';
const removable_str2 = 'ab#xyz.com;';
const result= full_str1.replace(removable_str2 , "");
console.log(result);
I try to transform string using String replace method and regular expression. How can I remove underscores in a given string?
let string = 'court_order_state'
string = string.replace(/_([a-z])/g, (_, match) => match.toUpperCase())
console.log(string)
Expected result:
COURT ORDER STATE
You could use JavaScript replace function, passing as input:
/_/g as searchvalue parameter (the g modifier is used to perform a global match, i.e. find all matches rather than stopping after the first one);
(blank space) as newvalue parameter.
let string = 'court_order_state'
string = string.replace(/_/g, ' ').toUpperCase();
console.log(string);
In your code you could match either and underscore or the start of the string (?:_|^) to also match the first word and match 1+ times a-z using a quantifier [a-z]+
Then append a space after each call toUpperCase.
let string = 'court_order_state';
string = string.replace(/(?:_|^)([a-z]+)/g, (m, g1) => g1.toUpperCase() + " ");
console.log(string)
let string = 'court_order_____state'
string = string.replace(/_+/g, ' ').toUpperCase()
console.log(string)
It can be as simple as the below:
let string = 'court_order_state'
string = string.replace(/_/g, ' ').toUpperCase();
console.log(string);
Here the 'g' represents global, whereas the '/' is surrounded by what we're looking for.
Instead of matching the first character just after every _ and making them uppercase (from the regex that you have used), you can simply convert the entire string to uppercase, and replace the _ with space by the following:
let string = 'court_order_state';
string = string.toUpperCase().replace(/_+/g, " ");
console.log(string);
Sorry if the wording is bad. So I'm trying to find out how to pass in a string match of multiple characters long into my dynamic regex expression.
The regex in my else statement works with 1 character being passed in so I'm trying to do the same thing except with multiple characters being passed in the first if statement.
const delimiter = str.slice(0, str.indexOf('\n'));
const strLength = delimiter.length;
if (delimiter[0] === '[' && delimiter.charAt(strLength - 1) === ']') {
const customDelimiter = delimiter.slice(delimiter.indexOf(delimiter[1]), delimiter.indexOf(delimiter.charAt(strLength - 1)));
console.log(customDelimiter) // => '***'
const regex = new RegExp(`,|\\n|\\${customDelimiter}`,'g');
return strArr = str.split(regex).filter(Boolean);
} else {
const firstChar = str.slice(0, 1); // => '*'
const regex = new RegExp(`,|\\n|\\${firstChar}`,'g');
return strArr = str.split(regex).filter(Boolean);
}
So for example I want this string:
'[*]\n11***22***33' to equal 66 b/c it should split it into an array of [11, 22, 33] using the '*' delimiter. I get an error message saying: "SyntaxError: Invalid regular expression: /,|\n|***/: Nothing to repeat".
When you use * as delimeter in your regex, it becomes ,|\\n|\\|\*, which is the correct regex.
It matches ',' or '\n' or a '*' character.
For your string, it matches [***]\n11***22***33.
But when you use *** as a delimiter in your regex, it becomes ,|\\n|\\|\***, which is incorrect. Here it gets two unescaped * at the end. * in regex means 0 or more of the preceding pattern. You cannot have two of them together.
This is a special case because * has a special meaning in regex.
If you would have used any non-regex character, it would work.
A simpler solution would be to use javascript split function to easily get the desired result.
You could first split the string using \n.
let splitStr = str.split('\n');
// This would return ["[***]", "11***22***33"]
and then split the 1st index of the splitStr using the delimeter.
splitStr[1].split('***');
// splitStr[1].split(customDelimiter)
// This would return ["11", "22", "33"]
Using this you wouldn't need to use if or else statement to separate out single character delimiter and multiple character delimiter.
Input
((Sass and Javascript) or (Python and Scala))
Delimiters -"(" and ")"
Output is an Array with the delimiters present as elements
["(","(","Sass and Javascript",")","or","(","Python and Scala",")",")"]
The problem that I am facing is this.
var arr = "((Sass and Javascript) or (Python and Scala))".split(/[(|)]/);
console.log(arr);
document.getElementById("output").innerHTML = arr;
<div id="output"></div>
When I use split on the string, I am losing the "(" and ")" characters and since they might occur anywhere in the string, I will need to insert them into the Array manually. Is there a better way to do this in JS?
You can use regex
/[()]|[^()]*/g
Regex Demo and Explanation
[()]: Matches ( or ) exactly once
|: OR
[^()]: Negated class, exclude ( and )
*: Match zero or more of the preceding class
g: Global match
Demo
var str = '((Sass and Javascript) or (Python and Scala))';
var matches = str.match(/[()]|[^()]*/g) || [];
matches.pop(); // Remove the last empty match from array
console.log(matches);
document.write('<pre>' + JSON.stringify(matches, 0, 2) + '</pre>');
Just simple
var string = '((Sass and Javascript) or (Python and Scala))';
var result = str.match(/[()]|[^()]*/g);
console.log(result)
var string = "abcdeabcde";
string = string.replace(/(/gi, ",(,");
string= string.replace(/)/gi, ",),");
var newstring = string.split(",");
return newstring;
You can use capturing parentheses in the split to simplify this a bit. (Note this is apparently not supported by all browsers. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split )
When you use capturing parentheses in a split regex, the captured delimiters are returned in the list along with the 'split' content.
"((Sass and Javascript) or (Python and Scala))".split(/\s*([()])\s*/)
Output
["", "(", "", "(", "Sass and Javascript", ")", "or", "(", "Python and Scala", ")", "", ")", ""]
You might need to process it afterwards to exclude zero-length elements.
var log = function(val){
console.log(val);
document.write('<pre>' + JSON.stringify(val , null , ' ') + '</pre>');
}
var firstStr = '((Sass and Javascript) or (Python and Scala))';
var secondStr = '{>Sass and Javascript< or [Python and Scala]}';
var firstArr = firstStr.match(/[^A-Za-z ]|[A-Za-z ]+/g);
var secondArr = secondStr.match(/[^A-Za-z ]|[A-Za-z ]+/g);
log(firstArr);
log(secondArr);
<div id ='el'></div>