0

Assume we have a string like the following :

,34,23,4,5,634,23,12,5,4,3,1234,23,54,,,,,,,123,43,2,3,4,5,3424,,,,,,,,123,,,1234,,,,,,,45,,,56

How can we convert it to the following string with RegExp in Javascript ?

34,23,4,5,634,12,3,1234,54,123,43,2,3424,45,56

Actually, I wanna remove repeated items and first and last , char

ninjagecko
  • 88,546
  • 24
  • 137
  • 145
Mohammad Dayyan
  • 21,578
  • 41
  • 164
  • 232

3 Answers3

4

[edited] To turn these into a set of unique numbers, as you are actually asking for, do this:

function scrapeNumbers(string) {
    var seen = {};
    var results = [];
    string.match(/\d+/g).forEach(function(x) {
        if (seen[x]===undefined)
            results.push(parseInt(x));
        seen[x] = true;
    });
    return results;
}

Demo:

> scrapeNumbers(',1,22,333,22,,333,4,,,')
[1, 22, 333, 4]

If you had an Array.prototype.unique() primitive, you could write it like so in one line:

yourString.match(/\d+/g).map(parseBase10).unique()

Unfortunately you need to be a bit verbose and define your own parseBase10 = function(n){return parseInt(n)} due to this ridiculous hard-to-track-down bug: javascript - Array#map and parseInt

Community
  • 1
  • 1
ninjagecko
  • 88,546
  • 24
  • 137
  • 145
  • That will remove duplicate commas quite nicely, but I believe the questioner wants to remove duplicate numbers as well. – Samuel Edwin Ward Mar 31 '12 at 22:53
  • 1
    @SamuelEdwinWard: oh, interesting, you should edit the bad question then rather than downvoting ;-) – ninjagecko Mar 31 '12 at 22:54
  • I agree the question isn't very well stated, but did you even read it? Does your code produce anything resembling his example? – Samuel Edwin Ward Mar 31 '12 at 22:57
  • @SamuelEdwinWard: It does now. – ninjagecko Mar 31 '12 at 23:10
  • It's still not a string though :) But I withdraw my downvote. Nothing personal of course. – Samuel Edwin Ward Mar 31 '12 at 23:13
  • shouldn't it be `parseInt(n,10)` to actually be "parseBase10"? – ajax333221 Apr 01 '12 at 01:17
  • @ajax333221: That would indeed make it explicit. However the base defaults to 10 except in cases where the number begins with '0x' (parsed as binary) or '0' (parsed as octal); thus it is unnecessary unless you expect numbers of the form `..,012,..`, in which case you would want to make that explicit. This is however not an issue which is related to this particular problem, as it would occur whenever you use the `parseInt` function in javascript, nomatter the context. It is an example of bad language design. – ninjagecko Apr 01 '12 at 02:29
1

No need for regex. Few tricks

text = ',34,23,4,5,634,23,12,5,4,3,1234,23,54,,,,,,,123,43,2,3,4,5,3424,,,,,,,,123,,,1234,,,,,,,45,,,56';
text = text.replace(/,+/g, ','); //replace two commas with one comma
text = text.replace(/^\s+|\s+$/g,''); //remove the spaces
textarray = text.split(","); // change them into array
textarray = textarray.filter(function(e){ return e.length});
console.log(textarray);                                       


// Now use a function to make the array unique
Array.prototype.unique = function(){
   var u = {}, a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(this[i] in u)
         continue;
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a;
}

textarray = textarray.unique();
text = textarray.join(','); //combine them back to what you want
console.log(text);

Demo

If you are familier with jQuery

text = text.replace(/,+/g, ',');
text = $.trim(text);
text = $.unique(text.split(",")).filter(function(e){ return e.length}).join(",");
console.log(text);

Demo

Starx
  • 77,474
  • 47
  • 185
  • 261
  • Good lord that phpjs code is really terrible. Your suggestion is basically correct but really nobody should use that stuff; it appears to have been written by somebody only barely familiar with JavaScript. – Pointy Mar 31 '12 at 23:01
  • @Pointy, On that case, updated with a prototype function. Hope you like it. – Starx Mar 31 '12 at 23:10
  • The prototype function is perfectly reasonable. However, won't the empty string `''` also be included in the results, and recombined into an arbitrary position? – ninjagecko Mar 31 '12 at 23:13
  • @ninjagecko, How about it now? May be you will remove the downvote now – Starx Mar 31 '12 at 23:44
  • @Starx: I'm not sure why you thought I downvoted you. Was someone else. – ninjagecko Mar 31 '12 at 23:47
  • @ninjagecko, I am sorry for the misunderstanding. – Starx Mar 31 '12 at 23:49
  • on the last jQuery example, you didn't prevent commas at the beginning/end – ajax333221 Apr 01 '12 at 01:22
  • @ajax333221, I have filtered at the third line. Please note – Starx Apr 01 '12 at 04:32
  • These Lines were very useful to me. `text = text.replace(/,+/g, ',');` and `text = $.trim(text);`... That combination worked very well. thx – ErickBest Aug 31 '14 at 11:17
0

This will do it:

function arrIndex(fnd, arr) {
    for (var len = arr.length, i = 0; i < len; i++) {
        if (i in arr && arr[i] === fnd) {
            return i;
        }
    }
    return -1;
}

function scrapeNumbers(str) {
    var arr = str.replace(/,+/g, ",").replace(/^,/, "").replace(/,$/, "").split(",");

    for (var i = 0, len = arr.length, rtn = []; i < len; i++) {
        if (i in arr && arrIndex(arr[i], rtn) == -1) {
            rtn.push(arr[i]);
        }
    }
    return rtn.join(",");
}

var str = ",,34,23,4,5,634,23,12,5,4,3,1234,23,54,,,,,,,123,43,2,3,4,5,3424,,,,,,,,123,,,1234,,,,,,,45,,,56,,";

alert(scrapeNumbers(str));

Here is a jsFiddle

Note: I created a custom array.indexOf function for a better browser support

ajax333221
  • 11,436
  • 16
  • 61
  • 95