What I want to do is take a string such as "this.those.that"
and get a substring to or from the nth occurrence of a character. So, from the start of the string to the 2nd occurrence of .
would return "this.those"
. Likewise, from the 2nd occurrence of .
to the end of the string would return "that"
. Sorry if my question is foggy, it's not that easy to explain. Also, please do not suggest making extra variables, and the result will be in a string and not an array.

- 5,495
- 3
- 19
- 29

- 1,823
- 7
- 23
- 29
-
1Any objection to splitting into an array, then joining slices of the arrays back together? It uses functions that either operate on strings or produce strings. – tvanfosson Mar 31 '11 at 02:26
-
1It seems you already know the answer; splitting the string on your separator and then reforming a new string with the parts seems the best option. Why limit yourself to not using an array? – Tejs Mar 31 '11 at 02:27
-
I wasn't specific enough. I don't want to make an extra array in addition to the string. Using array functions on the string works for what I'm trying to achieve. I'll fix the question. – Anonymous Mar 31 '11 at 02:40
-
@tvanfosson Why is my answer wrong? – alex Mar 31 '11 at 03:13
-
@tvanfosson I believe we may have interpreted the OP's question differently. – alex Mar 31 '11 at 14:07
-
@alex - I see. I took the example as the specific instance of n that he was interested in. You took it as for any given n produce a result and selected a different value for n. Seems reasonable. I withdraw my objection and delete my comment. – tvanfosson Mar 31 '11 at 14:13
5 Answers
You could do it without arrays, but it would take more code and be less readable.
Generally, you only want to use as much code to get the job done, and this also increases readability. If you find this task is becoming a performance issue (benchmark it), then you can decide to start refactoring for performance.
var str = 'this.those.that',
delimiter = '.',
start = 1,
tokens = str.split(delimiter).slice(start),
result = tokens.join(delimiter); // those.that
console.log(result)
// To get the substring BEFORE the nth occurence
var tokens2 = str.split(delimiter).slice(0, start),
result2 = tokens2.join(delimiter); // this
console.log(result2)
-
4I thought the result was supposed to be both "this.those" and "that"? – tvanfosson Mar 31 '11 at 02:45
-
-
-
5To get "this.those" and "that", change slice(start) to slice(0,start) – Dan Smart Oct 05 '15 at 15:17
-
@dan-smart To get both parts, "this" and "those.that", one has to take both slices, see [below](http://stackoverflow.com/a/34993640/2273305) – hooke Jan 25 '16 at 13:21
-
2Even shorter by using the optional limit parameter in split: result = str.split(delimiter, start+1).join(delimiter) – Daniël Teunkens Apr 28 '16 at 09:03
-
@DaniëlTeunkens Nice, I never realised `split()` could take a second argument. I can change the answer to suit. – alex Apr 28 '16 at 09:09
-
@DaniëlTeunkens It looks like the limit argument lets you stop splitting after so many matches, but in this case it wouldn't work because we want something like a *negative limit*, i.e. stop when splitting from right to left. – alex Apr 28 '16 at 09:16
Try this :
"qwe.fs.xczv.xcv.xcv.x".replace(/([^\.]*\.){3}/, '');
"xcv.xcv.x"
"qwe.fs.xczv.xcv.xcv.x".replace(/([^\.]*\.){**nth**}/, '');
- where is nth is the amount of occurrence to remove.

- 2,418
- 3
- 19
- 23

- 121
- 1
- 2
-
This one is better than the accepted answer. Sometimes the delimiter could be a regex (e.g. \s+). In such case, the accepted answer won't work. But this one will. – killua8p Jan 14 '16 at 05:21
-
@killua8p Odd reasoning. If *sometimes the delimiter could be a regex* you would design it as such. If it was to split on a string, you shouldn't always favour regex because *you may need it*. YAGNI. – alex Apr 28 '16 at 09:11
-
Just in case somebody needs both "this" and "those.that" in a way as alex described in his comment, here is a modified code:
var str = 'this.those.that',
delimiter = '.',
start = 1,
tokens = str.split(delimiter),
result = [tokens.slice(0, start), tokens.slice(start)].map(function(item) {
return item.join(delimiter);
}); // [ 'this', 'those.that' ]
document.body.innerHTML = result;
I'm perplexed as to why you want to do things purely with string functions, but I guess you could do something like the following:
//str - the string
//c - the character or string to search for
//n - which occurrence
//fromStart - if true, go from beginning to the occurrence; else go from the occurrence to the end of the string
var cut = function (str, c, n, fromStart) {
var strCopy = str.slice(); //make a copy of the string
var index;
while (n > 1) {
index = strCopy.indexOf(c)
strCopy = strCopy.substring(0, index)
n--;
}
if (fromStart) {
return str.substring(0, index);
} else {
return str.substring(index+1, str.length);
}
}
However, I'd strongly advocate for something like alex's much simpler code.

- 15,262
- 9
- 61
- 97
If you really want to stick to string methods, then:
// Return a substring of s upto but not including
// the nth occurence of c
function getNth(s, c, n) {
var idx;
var i = 0;
var newS = '';
do {
idx = s.indexOf(c);
newS += s.substring(0, idx);
s = s.substring(idx+1);
} while (++i < n && (newS += c))
return newS;
}

- 142,382
- 31
- 172
- 209