10

If I have the string:

var myStr = "foo_0_bar_0";

and I guess we should have a function called getAndIncrementLastNumber(str)

so if I do this:

myStr = getAndIncrementLastNumber(str); // "foo_0_bar_1"

Taking on considerations that there could be another text instead of foo and bar and there might not be underscores or there might be more than one underscore;

Is there any way with JavaScript or jQuery with .replace() and some RegEx?

Mr_Nizzle
  • 6,644
  • 12
  • 55
  • 85

7 Answers7

17

You can use the regular expression /[0-9]+(?!.*[0-9])/ to find the last number in a string (source: http://frightanic.wordpress.com/2007/06/08/regex-match-last-occurrence/). This function, using that regex with match(), parseInt() and replace(), should do what you need:

function increment_last(v) {
    return v.replace(/[0-9]+(?!.*[0-9])/, parseInt(v.match(/[0-9]+(?!.*[0-9])/), 10)+1);
}

Probably not terribly efficient, but for short strings, it shouldn't matter.

EDIT: Here's a slightly better way, using a callback function instead of searching the string twice:

function increment_last(v) {
    return v.replace(/[0-9]+(?!.*[0-9])/, function(match) {
        return parseInt(match, 10)+1;
    });
}
Brilliand
  • 13,404
  • 6
  • 46
  • 58
  • Nice that it works even if the last number isn't at the very end of the string. – Matt Coughlin Jun 15 '12 at 23:00
  • btw, in the first example, the `10` parameter is outside of the `parseInt()` parentheses. Still works fine, since the default radix is 10 and the extra `10` parameter added to `replace()` is ignored. – Matt Coughlin Jun 15 '12 at 23:11
  • @Matt: Fixed. Note that the default radix can become 8 in some situations (leading 0, specifically), which is why there's any point to putting the radix. – Brilliand Jun 15 '12 at 23:22
  • @Brilliand I'm not any good with Regex, in fact I don't know anything about that but.... now how can I get and increment the very first number in the string? it can be preceded with a text and so can have some text on the right too. Let's say now i have `foo_0_bar_0` and I want this to be `foo_1_bar_0` ... i was going to open a new question but you know, the context's already here. Thanks. – Mr_Nizzle Jun 18 '12 at 21:28
  • Regexes by default select the first match, so the regex to find the first number is much simpler: `/[0-9]+/` – Brilliand Jun 18 '12 at 21:30
7

Here's how I do it:

function getAndIncrementLastNumber(str) {
    return str.replace(/\d+$/, function(s) {
        return ++s;
    });
}

Fiddle

Or also this, special thanks to Eric:

function getAndIncrementLastNumber(str) {
    return str.replace(/\d+$/, function(s) {
        return +s+1;
    });
}

Fiddle

Fabrício Matté
  • 69,329
  • 26
  • 129
  • 166
  • `s+1` would make more sense here than `s++` – Eric Jun 15 '12 at 22:58
  • @Eric The ++s was to force the typecasting instead of using `parseInt`, well, I edited the answer now. =] – Fabrício Matté Jun 15 '12 at 23:01
  • Probably should specify the base to parseInt, as Matthew Schinckel indicated in an edit to my answer. – Brilliand Jun 15 '12 at 23:07
  • @Brilliand Thank you, I rarely use `parseInt` so forgetting the radix is one of my flaws. `:P` Sincerely, I'd just go with the first solution, as the `pre-increment` operator automatically casts the var to the integer and I find it more readable. – Fabrício Matté Jun 15 '12 at 23:13
  • @Eric, Oh, you! Wow, it's the first time I see casting a string to a number like that in JS. Learning something new everyday. Awesome man. `=]` – Fabrício Matté Jun 15 '12 at 23:17
  • This one work with the example string but can't get it working with a more complex string, thanks. check @Brilliand's answer. – Mr_Nizzle Jun 15 '12 at 23:17
  • @Mr_Nizzle: What does it fail on? – Eric Jun 15 '12 at 23:20
  • I'm not a regex expert, but 1 or more iterations of `0-9` digits in the end of a string as my regex represents, @Mr_Nizzle got me a little intrigued as to where it wouldn't work too. – Fabrício Matté Jun 15 '12 at 23:23
  • 1
    @Eric well this is an example of an id i'm trying to increment: `article_themes_attributes_0_theme_urls_attributes_0_url` it's now updating the number between `attributes_` and `_url` at the end of the string. – Mr_Nizzle Jun 15 '12 at 23:27
  • @Mr_Nizzle Oh yes, my regex is to match numbers at the very end of the string only (I probably missed some comment where you'd have text after the last number). – Fabrício Matté Jun 15 '12 at 23:28
  • @FabrícioMatté You're right, I didn't say that there might or might not be some text after the last number. – Mr_Nizzle Jun 15 '12 at 23:32
  • 1
    @Mr_Nizzle No problem, I won't bother updating the answer as you already have a fully working function, cya in some other question. `=]` – Fabrício Matté Jun 15 '12 at 23:45
1

try this demo please http://jsfiddle.net/STrR6/1/ or http://jsfiddle.net/Mnsy3/

code

existingId = 'foo_0_bar_0';
newIdOnly = existingId.replace(/foo_0_bar_(\d+)/g, "$1");
alert(newIdOnly);

getAndIncrementLastNumber(existingId);

function getAndIncrementLastNumber(existingId){
    alert(existingId);
newId = existingId.replace(/(\d+)/g, function(match, number) {
    return parseInt(number) + 1;
});
alert(newId);
}
​

or

   existingId = 'foo_0_bar_0';
newIdOnly = existingId.replace(/foo_0_bar_(\d+)/g, "$1");
alert(newIdOnly);

getAndIncrementLastNumber(existingId);

function getAndIncrementLastNumber(existingId){
    alert(existingId);
    newId = existingId.replace(/\d+$/g, function(number) {
    return parseInt(number) + 1;
});
alert("New ID ==> " + newId);
}
​
Tats_innit
  • 33,991
  • 10
  • 71
  • 77
  • First demo doesn't run and the second one updates both numbers inside string. having `foo_1_bar_1` when it should be `foo_0_bar_1`, check @Brilliand's answer. – Mr_Nizzle Jun 15 '12 at 23:20
  • @Mr_Nizzle Thanks it meant to be this - http://jsfiddle.net/Mnsy3/10/ this should work :), the second bout is just something extra if you need 2 integers to be incremented, thanks – Tats_innit Jun 15 '12 at 23:22
  • Yep @Mr_Nizzle because if you will see in code `existingId = 'foo_0_bar_0';` you can pull that dynamically according to your need. :) – Tats_innit Jun 15 '12 at 23:25
1

@Brilliant is right, +1, I just wanted to provide a version of his answer with 2 modifications:

  • Remove the unnecessary negative look-ahead operator.
  • Add the ability to add a number in the end, in case it doesn't exist.

```

/**
 * Increments the last integer number in the string. Optionally adds a number to it
 * @param {string} str The string
 * @param {boolean} addIfNoNumber Whether or not it should add a number in case the provided string has no number at the end
 */
function incrementLast(str, addIfNoNumber) {
    if (str === null || str === undefined) throw Error('Argument \'str\' should be null or undefined');
    const regex = /[0-9]+$/;
    if (str.match(regex)) {
        return str.replace(regex, (match) => {
            return parseInt(match, 10) + 1;
        });
    }
    return addIfNoNumber ? str + 1 : str;
}

Tests:

describe('incrementLast', () => {
        it('When 0', () => {
            assert.equal(incrementLast('something0'), 'something1');
        });
        it('When number with one digit', () => {
            assert.equal(incrementLast('something9'), 'something10');
        });
        it('When big number', () => {
            assert.equal(incrementLast('something9999'), 'something10000');
        });
        it('When number in the number', () => {
            assert.equal(incrementLast('1some2thing9999'), '1some2thing10000');
        });
        it('When no number', () => {
            assert.equal(incrementLast('1some2thing'), '1some2thing');
        });
        it('When no number padding addIfNoNumber', () => {
            assert.equal(incrementLast('1some2thing', true), '1some2thing1');
        });
    });
Andre Pena
  • 56,650
  • 48
  • 196
  • 243
0

in regex try this:

function getAndIncrementLastNumber(str){
   var myRe = /\d+[0-9]{0}$/g;  
   var myArray = myRe.exec(str);
   return parseInt(myArray[0])+1;​
}

demo : http://jsfiddle.net/F9ssP/1/

mgraph
  • 15,238
  • 4
  • 41
  • 75
0

Will the numbers be seperated with some characters? What I understood from you question is your string may look like this 78_asd_0_798_fgssdflh__0_2323 !! If this is the case, first you need to strip out all the characters and underscores in just one go. And then whatever you have stripped out you can either replace with comma or some thing.

So you will basically have str1: 78_asd_0_798_fgssdflh__0_2323 ; str2: 78,0,0,798,2323.

str2 need not be a string either you can just save them into a variable array and get the max number and increment it.

My next question is does that suffice your problem? If you have to replace the largest number with this incremented number then you have to replace the occurence of this number in str1 and replace it with your result.

Hope this helps. For replace using jquery, you can probably look into JQuery removing '-' character from string it is just an example but you will have an idea.

Community
  • 1
  • 1
Krishna
  • 169
  • 1
  • 8
0

If you want to only get the last number of string, Here is a good way using parseInt()

if(Stringname.substr(-3)==parseInt(Stringname.substr(-3)))
var b=Stringname.substr(-3);
else if(Stringname.substr(-2)==parseInt(Stringname.substr(-2)))
var b=Stringname.substr(-2);
else
var b=Stringname.substr(-1);

It checks and give the correct answer and store it in variable b for 1 digit number and upto 3 digit number. You can make it to any if you got the logic

sarath
  • 343
  • 8
  • 31