12

For string:

'29 July, 2014, 30 July, 2014, 31 July, 2014'

How can I split on every second comma in the string? So that my results are:

[0] => 29 July, 2014
[1] => 30 July, 2014
[2] => 31 July, 2014
pjmil
  • 2,087
  • 8
  • 25
  • 41

6 Answers6

17

Or this:

var text='29 July, 2014, 30 July, 2014, 31 July, 2014';
result=text.match(/([0-9]+ [A-z]+, [0-9]+)/g);

UPD: You can use this regExp to a find all matches:

//    result=text.match(/[^,]+,[^,]+/g);

    var text='string1, string2, string3, string4, string5, string 6';
    result=text.match(/[^,]+,[^,]+/g);

/*
result: 
string1, string2
string3, string4
string5, string 6
*/
SlyBeaver
  • 1,272
  • 12
  • 22
  • Of course! You can see it on jsfiddle [jsfiddle.net/y4rfE/](http://jsfiddle.net/y4rfE/). On jsfiddle I changed the code a bit, and code not depend only on the dates in string – SlyBeaver Jul 24 '14 at 10:43
  • oh! thanx for correcting my typo :) I am removing comments above to make it more clear; here is working fiddle without jQuery [link](http://jsfiddle.net/MarmeeK/5sakK/3/) – MarmiK Jul 24 '14 at 11:09
  • Carrying on your good work, howabout: s.match(/[^,]+,[^,]+/g) to make it even more generic? – sifriday Jul 24 '14 at 11:12
  • Yes, it's the best regexp. I'm added this code in answer. Thanks! – SlyBeaver Jul 24 '14 at 12:53
  • 1
    It does swallow last part for strings like - 'string1, string2, string3'. Suggestion to improve - match(/([^,]+,[^,]+)|([^,]+)/g); – Saulius Oct 08 '21 at 14:07
3

You can split with a regular expression. For example:

var s = '29 July, 2014, 30 July, 2014, 31 July, 2014';
s.split(/,(?= \d{2} )/)

returns

["29 July, 2014", " 30 July, 2014", " 31 July, 2014"]

This works OK if all your dates have 2 digits for the day part; ie 1st July will be printed as 01 July.

The reg exp is using a lookahead, so it is saying "split on a comma, if the next four characters are [space][digit][digit][space]".


Edit - I've just improved this by allowing for one or two digits, so this next version will deal with 1 July 2014 as well as 01 July 2014:

s.split(/,(?= \d{1,2} )/)

Edit - I noticed neither my nor SlyBeaver's efforts deal with whitespace; the 2nd and 3rd dates both have leading whitespace. Here's a split solution that trims whitespace:

s.split(/, (?=\d{1,2} )/)

by shifting the problematic space into the delimiter, which is discarded.

["29 July, 2014", "30 July, 2014", "31 July, 2014"]
sifriday
  • 4,342
  • 1
  • 13
  • 24
  • I was only a vaguely aware of it, so this question is giving me a good chance to try it out. What I am wondering it, is there any merit to doing a split versus a global match as suggested by SlyBeaver further down? – sifriday Jul 24 '14 at 10:19
  • It's a match too. moreover this method can't parse this string: `string1, string2, string3, string4, string5, string 6`. But my method can it ;) – SlyBeaver Jul 24 '14 at 10:52
  • It does feel like the goal has to be a regexp that splits/matches on the second comma regardless of the date, doesn't it? I'm starting to think match makes this easier to build the right regexp. I wonder if there is a performance difference? – sifriday Jul 24 '14 at 11:11
  • I think regexp slowly. But it's simple Javascript and it may be not critical – SlyBeaver Jul 24 '14 at 14:25
  • I did a very quick test, and match beats split. But I had to run 100,000 iterations to get a tenth of a second difference. So yeah, premature optimisation :-) – sifriday Jul 24 '14 at 14:38
2

Not sure if you can do it in a one-liner, but a workaround would be to split on every comma then join consecutive values.

ex:

var str = '29 July, 2014, 30 July, 2014, 31 July, 2014';
var list = str.split(",");
var list2 =[];
for (var i=0;i<list.length; i+=2){
    list2.push(list[i]+","+list[i++]);
}
Alexandru Severin
  • 6,021
  • 11
  • 48
  • 71
  • Just curious, this for loop doesn't look like it will traverse the entire array length because you have list.length/2 – g00dnatur3 Jul 24 '14 at 10:02
1

Like this

 var str = '29 July, 2014, 30 July, 2014, 31 July, 2014'

 var parts = str.split(',')

 var answer = []

 for (var i=0; i<parts.length; i++) {
        if (i < 1) continue;
        if (i % 2 == 1) {
           answer.push(parts[i-1] + ',' + parts[i]);
        }
 }

 console.log(answer)
g00dnatur3
  • 1,173
  • 9
  • 16
  • so at i=1, it will concat parts[0] + ',' + parts[1] and push that to answer[0], and at i=3 it will concat parts[2] + ',' + parts[3] and push that to answer[1] and so on and so forth... – g00dnatur3 Jul 24 '14 at 09:59
  • Although i really like the regular expression ansewr alot, this solution is not dependent on the format of your data.. it will just split on every second ',' regardless of what format your data is. – g00dnatur3 Jul 24 '14 at 10:06
1

I know it's almost two years ago.

This function is reusable.

String.prototype isn't necessary to make it work.. But it's easy..

String.prototype.splitEvery = function ( splitter, every ){

    var array = this.split( splitter), newString = '', thisSplitter; 

    $.each( array, function( index, elem ){ 

        thisSplitter = ( index < array.length - 1 || index % every === 0 ) ? '' : splitter;

        newString += elem + thisSplitter;                                                               
    });          

    return newString;                                                                                   
};  


var dateString = '29 July, 2014, 30 July, 2014, 31 July, 2014';

The usage in this case is:

dateString.splitEvery( ',', 2 );

First parameter is the split, second is how many is between each.

Result are:

29 July 2014, 30 July 2014, 31 July 2014
0

This is not a refactored solution, but it works:

var $dates = '29 July, 2014, 30 July, 2014, 31 July, 2014';
$dates = $dates.split(',');
$result = [];
$dateValue = '';

for($i=0 ; $i<$dates.length ; $i++) {
if($i % 2 != 0 && $i > 0) {
            $dateValue += ','+$dates[$i];
    $result.push($dateValue);
    $dateValue = '';
} else {
    $dateValue += $dates[$i];
}
}

console.log($result);
Mario Araque
  • 4,562
  • 3
  • 15
  • 25