views:

262

answers:

7

How can I split a string only once, i.e. make 1|Ceci n'est pas une pipe: | Oui parse to: ["1", "Ceci n'est pas une pipe: | Oui"]?

The limit in split doesn't seem to help...

+5  A: 

You can use:

var splits = str.match(/([^|]*)\|(.*)/);
splits.shift();

The regex splits the string into two matching groups (parenthesized), the text preceding the first | and the text after. Then, we shift the result to get rid of the whole string match (splits[0]).

Matthew Flaschen
Tested this code and works. 1+ for using Regex.
Riley
properly, that should probably anchor at beginning. however javascript regexen seem to be greedy.
sreservoir
Ah, thanks for that, that should work!
Stavros Korokithakis
+2  A: 

Try this:

function splitOnce(input, splitBy) {
    var fullSplit = input.split(splitBy);
    var retVal = [];
    retVal.push( fullSplit.shift() );
    retVal.push( fullSplit.join( splitBy ) );
    return retVal;
}

var whatever = splitOnce("1|Ceci n'est pas une pipe: | Oui", '|');
Josh the Goods
+5  A: 

This isn't a pretty approach, but works with decent efficiency:

var string = "1|Ceci n'est pas une pipe: | Oui";
var components = string.split('|');
alert([components.shift(), components.join('|')]​);​​​​​

Here's a quick demo of it

Nick Craver
+1 That's pretty clever. (you might want to paste the working code back here).
karim79
@karim - Clarify on the working code bit? Confusing me!
Nick Craver
This is actually better than the regex, I think. Selected as correct, thanks!
Stavros Korokithakis
To clarify, he's splitting into N parts then popping the first one onto a list and joining the rest onto the same list.
Stavros Korokithakis
@Nick - discrepancy between the code above and the code in jsfiddle. There's an extra `);` in the alert above.
karim79
@karim - Ahhh thanks! fixed the answer
Nick Craver
A: 

use the javascript regular expression functionality and take the first captured expression.

the RE would probably look like /^([^|]*)\|/.

actually, you only need /[^|]*/ if you validated that the string is formatted in such a way, due to javascript regex greediness.

sreservoir
+3  A: 

You'd want to use String.indexOf('|') to get the index of the first occurrence of '|'.

var i = s.indexOf('|');
var splits = [s.slice(0,i), s.slice(i+1)];
yarmiganosca
This is also a good solution.
Stavros Korokithakis
A: 

Just as evil as most of the answers so far:

var splits = str.split('|');
splits.splice(1, splits.length - 1, splits.slice(1).join('|'));
wombleton
A: 

An alternate, short approach, besides the goods ones elsewhere, is to use replace()'s limit to your advantage.

var str = "1|Ceci n'est pas une pipe: | Oui";
str.replace("|", "aUniquePhraseToSaySplitMe").split("aUniquePhraseToSaySplitMe");

As @sreservoir points out in the comments, the unique phrase must be truly unique--it cannot be in the source you're running this split over, or you'll get the string split into more pieces than you want. An unprintable character, as he says, may do if you're running this against user input (i.e., typed in a browser).

D_N
that only works if the 'unique' phrase is uninputable. if reading from a text file, this is impossible. if reading from browser, any unprintable control character if probably fine. tab works wonders, too. in any case, "aUniquePhraseToSaySplitMe" is almost definitely possibly part of the input, and is thus dangerous.
sreservoir
You are correct, of course. My example is just an example with an eye toward explaining what is being done concisely. I'll incorporate your point into the answer itself. Thanks!
D_N