Javascript - How to use variable separator for split function? - javascript

I have some function that uses split, but I want the separator to be a variable. separator will be used several places and it would be nice to only have to change the variable once rather than change hard code everywhere.
But, of course, it doesn't work. The pattern looks correct, but split must have some problem with variables defining the split.
Here is some testing I did in Google Chrome's console.
separator = '|'; // separator to use
var pattern = '/\\' + separator + '\\s*/'; // define pattern
undefined
pattern;
"/\|\s*/"
// pattern is correct
// now define function with constant... variable version commented:
function split( val ) {
//var pattern = '/\\' + separator + '\\s*/';
return val.split( /\|\s*/ );
//return val.split( pattern );
}
undefined
split('asdf|jkl');
["asdf", "jkl"]
// function worked as expected
// now uncomment the variable portions:
function split( val ) {
var pattern = '/\\' + separator + '\\s*/';
//return val.split( /\|\s*/ );
return val.split( pattern );
}
undefined
split('asdf|jkl');
["asdf|jkl"]
// not as expected. string is not split into array
I assume this has something to do with the split function. How do I get this to work? Note that the only reason I think I need to do it this way is because I want to easily be able to change separator. If not for that, I could just hard code everything it would work.
EDIT:
I don't care if it uses regex or not. But it needs to split the string on separator and also make sure the values are trimmed of extra spaces.
Also, I'm modeling my code after the jQuery UI page for autocomplete, here.
And here's the function as they have it. I don't know why they define their own split.
function split( val ) {
return val.split( /,\s*/ );
}

Concat the string, and use it to create an instance of a new RegExp obj.
function split( val ) {
var pattern = new RegExp('\\' + separator + '\\s*');
return val.split( pattern );
}
EDITS
Note that in this particular example, there doesn't appear to be any value over String.prototype.split().
This would be more useful if you wanted to set a limit for all splits of a certain type:
function split( val ) {
var pattern = new RegExp('\\' + separator + '\\s*');
return val.split( pattern , 3);
}
without having to write:
strVar.split(pattern, 3);
Yes, that limit can be stored as a variable and referenced, but then you have to expose that variable throughout the scope of every function you want to use it in.
What if you wanted to change it so it would take an array of strings to split, instead?

You can split on a string or on a regular expression,
but don't mix them up-
var separator='|', val='Split | on | the | pipes';
val.split(RegExp('\\' + separator + '\\s*')).join('\n');
/* returned value: (String)
Split
on
the
pipes
*/

Please use split() and don't have a hard time making your own function
http://www.w3schools.com/jsref/jsref_split.asp
A quick example
<p id="demo">Click the button to display the array values after the split.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction()
{
var str="How are you doing today?";
var n=str.split(" ");
document.getElementById("demo").innerHTML=n;
}
</script>
then just put the pattern on the split() parameter. make sure escape any character you will put on the parameter because the split() thinks you entered a regex. Your | separator is a regex special character and you must escape it with a backslash

Best way is to just use String.split as it can split by using strings itself.
But as you wish to explore RegEx, you need to ensure the separator is correctly escaped before attempting the split:
Here is a working function where separator can be any string:
function split(val, separator) {
var separator = separator.replace(/([^\w\s])/g, '\\$1');
return val.split(new RegExp(separator));
}
split("String|$Array|$Objects", "|$");
> Result ["String", "Array", "Objects"]

Related

Using RegExp to substring a string at the position of a special character

Suppose I have a sting like this: ABC5DEF/G or it might be ABC5DEF-15 or even just ABC5DEF, it could be shorter AB7F, or AB7FG/H.
I need to create a javascript variable that contains the substring only up to the '/' or the '-'. I would really like to use an array of values to break at. I thought maybe to try something like this.
...
var srcMark = array( '/', '-' );
var whereAt = new RegExp(srcMark.join('|')).test.str;
alert("whereAt= "+whereAt);
...
But this returns an error: ReferenceError: Can't find variable: array
I suspect I'm defining my array incorrectly but trying a number of other things I've been no more successful.
What am I doing wrong?
Arrays aren't defined like that in JavaScript, the easiest way to define it would be with:
var srcMark = ['/','-'];
Additionally, test is a function so it must be called as such:
whereAt = new RegExp(srcMark.join('|')).test(str);
Note that test won't actually tell you where, as your variable suggests, it will return true or false. If you want to find where the character is, use String.prototype.search:
str.search(new RegExp(srcMark.join('|'));
Hope that helps.
You need to use the split method:
var srcMark = Array.join(['-','/'],'|'); // "-|/" or
var regEx = new RegExp(srcMark,'g'); // /-|\//g
var substring = "222-22".split(regEx)[0] // "222"
"ABC5DEF/G".split(regEx)[0] // "ABC5DEF"
From whatever i could understand from your question, using this RegExp /[/-]/ in split() function will work.
EDIT:
For splitting the string at all special characters you can use new RegExp(/[^a-zA-Z0-9]/) in split() function.
var arr = "ABC5DEF/G";
var ans = arr.split(/[/-]/);
console.log(ans[0]);
arr = "ABC5DEF-15";
ans = arr.split(/[/-]/);
console.log(ans[0]);
// For all special characters
arr = "AB7FG/H";
ans = arr.split(new RegExp(/[^a-zA-Z0-9]/));
console.log(ans[0]);
You can use regex with String.split.
It will look something like that:
var result = ['ABC5DEF/G',
'ABC5DEF-15',
'ABC5DEF',
'AB7F',
'AB7FG/H'
].map((item) => item.split(/\W+/));
console.log(result);
That will create an Array with all the parts of the string, so each item[0] will contain the text till the / or - or nothing.
If you want the position of the special character (non-alpha-numeric) you can use a Regular Expression that matches any character that is not a word character from the basic Latin alphabet. Equivalent to [^A-Za-z0-9_], that is: \W
var pattern = /\W/;
var text = 'ABC5DEF/G';
var match = pattern.exec(text);
var position = match.index;
console.log('character: ', match[0]);
console.log('position: ', position);

Replacing an integer (n) with a character repeated n times

Let's say I have a string:
"__3_"
...which I would like to turn into:
"__###_"
basically replacing an integer with repeated occurrences of # equivalent to the integer value. How can I achieve this?
I understand that backreferences can be used with str.replace()
var str = '__3_'
str.replace(/[0-9]/g, 'x$1x'))
> '__x3x_'
And that we can use str.repeat(n) to repeat string sequences n times.
But how can I use the backreference from .replace() as the argument of .repeat()? For example, this does not work:
str.replace(/([0-9])/g,"#".repeat("$1"))
"__3_".replace(/\d/, function(match){ return "#".repeat(+match);})
if you use babel or other es6 tool it will be
"__3_".replace(/\d/, match => "#".repeat(+match))
if you need replace __11+ with "#".repeat(11) - change regexp into /\d+/
is it what you want?
According https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
str.replace(regexp|substr, newSubStr|function)
and if you use function as second param
function (replacement)
A function to be invoked to create the new substring (to put in place of the >substring received from parameter #1). The arguments supplied to this function >are described in the "Specifying a function as a parameter" section below.
Try this:
var str = "__3_";
str = str.replace(/[0-9]+/, function(x) {
return '#'.repeat(x);
});
alert(str);
Old fashioned approach:
"__3__".replace(/\d/, function (x) {
return Array(+x + 1).join('#');
});
Try this:
var str = "__3_";
str = str.replace(/[0-9]/g,function(a){
var characterToReplace= '#';
return characterToReplace.repeat(a)
});

Javascript convert PascalCase to underscore_case/snake_case

How can I convert PascalCase string into underscore_case/snake_case string? I need to convert dots into underscores as well.
eg. convert
TypeOfData.AlphaBeta
into
type_of_data_alpha_beta
You could try the below steps.
Capture all the uppercase letters and also match the preceding optional dot character.
Then convert the captured uppercase letters to lowercase and then return back to replace function with an _ as preceding character. This will be achieved by using anonymous function in the replacement part.
This would replace the starting uppercase letter to _ + lowercase_letter.
Finally removing the starting underscore will give you the desired output.
var s = 'TypeOfData.AlphaBeta';
console.log(s.replace(/(?:^|\.?)([A-Z])/g, function (x,y){return "_" + y.toLowerCase()}).replace(/^_/, ""));
OR
var s = 'TypeOfData.AlphaBeta';
alert(s.replace(/\.?([A-Z])/g, function (x,y){return "_" + y.toLowerCase()}).replace(/^_/, ""));
any way to stop it for when a whole word is in uppercase. eg. MotorRPM into motor_rpm instead of motor_r_p_m? or BatteryAAA into battery_aaa instead of battery_a_a_a?
var s = 'MotorRMP';
alert(s.replace(/\.?([A-Z]+)/g, function (x,y){return "_" + y.toLowerCase()}).replace(/^_/, ""));
str.split(/\.?(?=[A-Z])/).join('_').toLowerCase();
u're welcome
var s1 = 'someTextHere';
var s2 = 'SomeTextHere';
var s3 = 'TypeOfData.AlphaBeta';
var o1 = s1.split(/\.?(?=[A-Z])/).join('_').toLowerCase();
var o2 = s2.split(/\.?(?=[A-Z])/).join('_').toLowerCase();
var o3 = s3.split(/\.?(?=[A-Z])/).join('_').toLowerCase();
console.log(o1);
console.log(o2);
console.log(o3);
Alternatively using lodash:
lodash.snakeCase(str);
Example:
_.snakeCase('TypeOfData.AlphaBeta');
// ➜ 'type_of_data_alpha_beta'
Lodash is a fine library to give shortcut to many everyday js tasks.There are many other similar string manipulation functions such as camelCase, kebabCase etc.
This solution solves the non-trailing acronym issue with the solutions above
I ported the code in 1175208 from Python to JavaScript.
Javascript Code
function camelToSnakeCase(text) {
return text.replace(/(.)([A-Z][a-z]+)/, '$1_$2').replace(/([a-z0-9])([A-Z])/, '$1_$2').toLowerCase()
}
Working Examples:
camelToSnakeCase('thisISDifficult') -> this_is_difficult
camelToSnakeCase('thisISNT') -> this_isnt
camelToSnakeCase('somethingEasyLikeThis') -> something_easy_like_this
"alphaBetaGama".replace(/([A-Z])/g, "_$1").toLowerCase() // alpha_beta_gamma
Problem - Need to convert a camel-case string ( such as a property name ) into underscore style to meet interface requirements or for meta-programming.
Explanation
This line uses a feature of regular expressions where it can return a matched result ( first pair of () is $1, second is $2, etc ).
Each match in the string is converted to have an underscore ahead of it with _$1 string provided. At that point the string looks like alpha_Beta_Gamma.
To correct the capitalization, the entire string is converted toLowerCase().
Since toLowerCase is a fairly expensive operation, its best not to put it in the looping handler for each match-case, and run it once on the entire string.
After toLowerCase it the resulting string is alpha_beta_gamma ( in this example )
This will get you pretty far: https://github.com/domchristie/humps
You will probably have to use regex replace to replace the "." with an underscore.
I found this but I edited it so suit your question.
const camelToSnakeCase = str => str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`).replace(/^_/,'')
Good examples for js:
Snake Case
Kebab Case
Camel Case
Pascal Case
have here
function toCamelCase(s) {
// remove all characters that should not be in a variable name
// as well underscores an numbers from the beginning of the string
s = s.replace(/([^a-zA-Z0-9_\- ])|^[_0-9]+/g, "").trim().toLowerCase();
// uppercase letters preceeded by a hyphen or a space
s = s.replace(/([ -]+)([a-zA-Z0-9])/g, function(a,b,c) {
return c.toUpperCase();
});
// uppercase letters following numbers
s = s.replace(/([0-9]+)([a-zA-Z])/g, function(a,b,c) {
return b + c.toUpperCase();
});
return s;
}
Try this function, hope it helps.
"TestString".replace(/[A-Z]/g, val => "_" + val.toLowerCase()).replace(/^_/,"")
replaces all uppercase with an underscore and lowercase, then removes the leading underscore.
A Non-Regex Answer that converts PascalCase to snake_case
Note: I understand there are tons of good answers which solve this question elegantly. I was recently working on something similar to this where I chose not to use regex. So I felt to answer a non-regex solution to this.
const toSnakeCase = (str) => {
return str.slice(0,1).toLowerCase() + str.split('').slice(1).map((char) => {
if (char == char.toUpperCase()) return '_' + char.toLowerCase();
else return char;
}).join('');
}
Eg.
inputString = "ILoveJavascript" passed onto toSnakeCase()
would become "i_love_javascript"

RegExp to strip a variable in ES6-like format

I'm using an ES6-like variable formatting with the syntax of ${varName}, and while processing them I'm trying to enumerate all unique variables specified, using the following code:
function enumVars(txt) {
var v, names = [];
var reg = /\$\{\s*[a-zA-Z\$_][a-zA-Z0-9\$_]*\s*}/g;
while (v = reg.exec(txt)) {
var svn = v[0].replace(/???/, ''); // stripped variable name;
if (names.indexOf(svn) === -1) {
names.push(svn);
}
}
return names;
}
I haven't been able to figure out the correct RegExp for stripping the variable name from the exec result.
When I use v[0], it gives me ${varName} string, and I need to strip it into just varName, removing leading ${, trailing }, and all white spaces that may reside inside { } around the variable.
The variable is expected to follow the javascript naming convention, which means:
a valid variable starts with a letter, underscore or '$' symbol, followed by any combination of letters, digits, underscores or '$';
leading and trailing spaces around the variable are to be ignored.
In all, we may have a variable returned from exec as ${ _$abc12_$ }, and I need a RegExp for calling replace that would return just _$abc12_$.
Thanks everyone for helping!
Your replace regexp could be
/^\$\{\s*|\s*}$/g
In English, this says "remove both ${... at the beginning, or ...} at the end.
It could be slightly easier to just grab all the strings, and transform them all at once, then filter out duplicates:
function enumVars(txt) {
return txt
// Find all matches of form ${var}
. match(/\$\{\s*[a-z$_][a-z0-9$_]*\s*}/gi)
// Strip off ${ and }, yielding just variable name
. map(function(v) { return v.replace( /^\$\{\s*|\s*}$/g, ''); })
// Filter out duplicates
. filter(function(v, i, a) { return a.indexOf(v) === i; });
}

Javascript regexp: replacing $1 with f($1)

I have a regular expression, say /url.com\/([A-Za-z]+)\.html/, and I would like to replace it with new string $1: f($1), that is, with a constant string with two interpolations, the captured string and a function of the captured string.
What's the best way to do this in JavaScript? 'Best' here means some combination of (1) least error-prone, (2) most efficient in terms of space and speed, and (3) most idiomatically appropriate for JavaScript, with a particular emphasis on #3.
The replace method can take a function as the replacement parameter.
For example:
str.replace(/regex/, function(match, group1, group2, index, original) {
return "new string " + group1 + ": " + f(group1);
});
When using String.replace, you can supply a callback function as the replacement parameter instead of a string and create your own, very custom return value.
'foo'.replace(/bar/, function (str, p1, p2) {
return /* some custom string */;
});
.replace() takes a function for the replace, like this:
var newStr = string.replace(/url.com\/([A-Za-z]+)\.html/, function(all, match) {
return match + " something";
});
You can transform the result however you want, just return whatever you want the match to be in that callback. You can test it out here.

Categories