'Split string with limit, where last string contains the remainder
e.g. if I run this javascript:
var str = 'hello_world_there';
var parts = str.split('_', 2);
var p1 = parts[0];
var p2 = parts[1];
at the end, p1 contains "hello", and p2 contains "world".
I'd like p1 to contain "hello", and p2 to contain "world_there". i.e. I want p2 to contain the rest of the string, regardless of how many underscores it has (similar to how c#'s String.Split(char[] separator, int count) behaves.
Any workarounds ?
Solution 1:[1]
This is slightly different from taking the rest as is, but this was useful in my case:
const [a, ...b] = 'foo/bar/baz'.split('/');
// => a: 'foo', b: ['bar', 'baz']
Solution 2:[2]
Write your own function:
function split(string, delimiter, n) {
var parts = string.split(delimiter);
return parts.slice(0, n - 1).concat([parts.slice(n - 1).join(delimiter)]);
}
Solution 3:[3]
Just try with:
var parts = str.split('_', 2);
var p1 = parts.shift();
var p2 = parts.join('_');
or:
var index = str.indexOf('_');
var p1 = str.substr(0, index);
var p2 = str.substr(index + 1);
Solution 4:[4]
For your specific case where you just want two parts, the simplest thing is indexOf and substring:
const index = text.indexOf("_");
const p0 = index === -1 ? text : text.substring(0, index);
const p1 = index === -1 ? "" : text.substring(index + 1);
Live Example:
const text = "hello_world_there";
const index = text.indexOf("_");
const p0 = index === -1 ? text : text.substring(0, index);
const p1 = index === -1 ? "" : text.substring(index + 1);
console.log(`p0 = "${p0}", p1 = "${p1}"`);
I've found I want that often enough I have it in a utility module:
const twoParts = (str, delim = " ") => {
const index = str.indexOf("_");
if (index === -1) {
return [str, ""];
}
return [
str.substring(0, index),
str.substring(index + delim.length),
];
};
But if you wanted to do more than just teh two parts, an approach that doesn't require rejoining the string after the fact would be to use a regular expression with capture groups:
const result = text.match(/^([^_]+)_+([^_]+)_+(.*)$/);
const [_, p0 = "", p1 = "", p2 = ""] = result ?? [];
Live Example:
const text = "hello_world_xyz_there";
const result = text.match(/^([^_]+)_+([^_]+)_+(.*)$/);
const [_, p0 = "", p1 = "", p2 = ""] = result ?? [];
console.log(`p0 = "${p0}", p1 = "${p1}", p2 = "${p2}"`);
Solution 5:[5]
Regexp solution (you can change "|" to other chars e.g. "__" but not to "_")
var [p1,p2] = str.replace(/_/,"|").split("|");
let str = 'hello_world_there'
let [p1,p2] = str.replace(/_/,"|").split("|");
console.log("p1:",p1);
console.log("p2:",p2);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | amiq11 |
| Solution 2 | Blender |
| Solution 3 | hsz |
| Solution 4 | T.J. Crowder |
| Solution 5 | Kamil Kiełczewski |
