views:

161

answers:

4

How can I catch everything after the last underscore in a filename?

ex: 24235235adasd_4.jpg into 4.jpg

Thanks again!

+10  A: 
var end = "24235235adasd_4.jpg".match(/.*_(.*)/)[1];

Edit: Whoops, the ungreedy modifier was wrong.

Edit 2: After running a benchmark, this is the slowest method. Don't use it ;) Here is the benchmark and the results.

Benchmark:

var MAX     = 100000,     i =  0, 
    s       = new Date(), e = new Date(), 
    str     = "24235235ad_as___4.jpg",
    methods = {
        "Matching":  function() { return str.match(/.*_(.*)/)[1];               },
        "Substr":    function() { return str.substr(str.lastIndexOf('_') + 1);  },
        "Split/pop": function() { return str.split('_').pop();                  },
        "Replace":   function() { return str.replace(/.*_/,'');                 }
    };

console.info("Each method over %d iterations", MAX);
for ( var m in methods ) {
    if ( !methods.hasOwnProperty(m) ) { continue; }
    i = 0;

    s = new Date();
    do {
        methods[m]();
    } while ( ++i<MAX );
    e = new Date();

    console.info(m);
    console.log("Result: '%s'", methods[m]());
    console.log("Total: %dms; average: %dms", +e - +s, (+e - +s) / MAX);
}

Results:

Each method over 100000 iterations
Matching
Result: '4.jpg'
Total: 1079ms; average: 0.01079ms
Substr
Result: '4.jpg'
Total: 371ms; average: 0.00371ms
Split/pop
Result: '4.jpg'
Total: 640ms; average: 0.0064ms
Replace
Result: '4.jpg'
Total: 596ms; average: 0.00596ms

Gordon Tucker's Substr/lastIndexOf is the fastest by a long shot.

Justin Johnson
+1 for self critic and benchmark
Tim Büthe
Thanks Tim! (15charfiller)
Justin Johnson
Different JavaScript/ECMAScript implementations will perform this benchmark differently. Out of curiosity which engine was used for the results here? It would be really interesting to see if there was any variation in results on other engines. Thanks for taking the time to do this!
McKAMEY
Total MS for 100000Matching, Substr, Split/pop, Replace**IE 8**`538, 118, 427, 336;`**FF 3.5.5**`221, 18, 62, 119;`**Chrome 4.0.223.16**`57, 27, 152, 35;`**Safari 530.17**`135, 52, 55, 42;`**Opera 10.10**`258, 152, 156, 402;`
McKAMEY
My test was on FF 3.5.5/OS X 10 .5.8
Justin Johnson
+1 for running benchmarks. You rock.
JoshBaltzell
Thanks mate. I do my best ;)
Justin Johnson
+9  A: 
"24235235adasd_4.jpg".split('_').pop();
McKAMEY
+1 Since this returns everything past the LAST underscore
Matt
+1 for most readable code, and for allowing input with *no* underscores
Jørn Schou-Rode
Readable yes, but all other responses besides my own work with or without underscores.
Justin Johnson
+11  A: 
var foo = '24235235adasd_4.jpg';
var bar = foo.substr(foo.lastIndexOf('_') + 1);

*Make a note to yourself that this wont work with those uncommon files that have an '_' in their extension (for example, I've seen some that are named filename.tx_)

Gordon Tucker
+1 this seems to be the fastest way to do this task
János Harsányi
You have one too many closing `)`.
Justin Johnson
+1 This *is* the fastest method. See my answer for the benchmark.
Justin Johnson
I had it wrapped in an `alert()` before and missed removing the closing `)` when I pasted the code. All fixed now :)
Gordon Tucker
This really helped me out. Thanks a lot.
JoshBaltzell
A: 
var end = filename.replace(/.*_/,'');
Jeff B