241

What would be the cleanest way of doing this that would work in both IE and Firefox?

My string looks like this sometext-20202

Now the sometext and the integer after the dash can be of varying length.

Should I just use substring and index of or are there other ways?

Gottlieb Notschnabel
  • 9,408
  • 18
  • 74
  • 116
mrblah
  • 99,669
  • 140
  • 310
  • 420

14 Answers14

379

How I would do this:

// function you can use:
function getSecondPart(str) {
    return str.split('-')[1];
}
// use the function:
alert(getSecondPart("sometext-20202"));
artlung
  • 33,305
  • 16
  • 69
  • 121
201

A solution I prefer would be:

const str = 'sometext-20202';
const slug = str.split('-').pop();

Where slug would be your result

RPL
  • 3,500
  • 2
  • 21
  • 28
  • 8
    This solutions is the best if you are working with multiple delimiters. – Ethan Keiley Jun 12 '20 at 00:08
  • 3
    This solution gets you everything after the *last* dash. Personally, I interpret "everything after the dash" as everything after the *first* dash, but that seems open to interpretation. – Tao Jun 23 '22 at 17:10
  • Does not produce expected result if separator is not present at all. @kcsoft's answer works for me. – Suresh Kumar Aug 21 '23 at 10:25
77
var testStr = "sometext-20202"
var splitStr = testStr.substring(testStr.indexOf('-') + 1);
Mohammad Usman
  • 37,952
  • 20
  • 92
  • 95
Kanke
  • 2,527
  • 16
  • 10
  • 1
    I feel that this is quite simple and straightforward for what I was trying to accomplish. Thank you. – JerrySeinfeld Mar 28 '21 at 00:40
  • 3
    Unlike the two higher-voted answers, this one actually correctly addresses the question as stated, "everything after the dash", even if there are more dashes in that "everything". – Tao Jun 23 '22 at 17:08
32
var the_string = "sometext-20202";
var parts = the_string.split('-', 2);

// After calling split(), 'parts' is an array with two elements:
// parts[0] is 'sometext'
// parts[1] is '20202'

var the_text = parts[0];
var the_num  = parts[1];
Sean Bright
  • 118,630
  • 17
  • 138
  • 146
  • This code for the above-discussed case (having more than one delimiter ), will not work. Because the string gets split at every delimiter but only the first two parts will be considered, all other parts are simply omitted. – Anu Dec 22 '22 at 06:16
13

With built-in javascript replace() function and using of regex (/(.*)-/), you can replace the substring before the dash character with empty string (""):

"sometext-20202".replace(/(.*)-/,""); // result --> "20202"
Mahyar Ekramian
  • 191
  • 2
  • 5
8
myString.split('-').splice(1).join('-')
kcsoft
  • 2,917
  • 19
  • 14
7

AFAIK, both substring() and indexOf() are supported by both Mozilla and IE. However, note that substr() might not be supported on earlier versions of some browsers (esp. Netscape/Opera).

Your post indicates that you already know how to do it using substring() and indexOf(), so I'm not posting a code sample.

Cerebrus
  • 25,615
  • 8
  • 56
  • 70
4

For those trying to get everything after the first occurrence:

Something like "Nic K Cage" to "K Cage".

You can use slice to get everything from a certain character. In this case from the first space:

const delim = " "
const name = "Nic K Cage"

const result = name.split(delim).slice(1).join(delim) // prints: "K Cage"

Or if OP's string had two hyphens:

const text = "sometext-20202-03"
// Option 1
const opt1 = text.slice(text.indexOf('-')).slice(1) // prints: 20202-03
// Option 2
const opt2 = text.split('-').slice(1).join("-")     // prints: 20202-03
Steve
  • 4,372
  • 26
  • 37
3

I came to this question because I needed what OP was asking but more than what other answers offered (they're technically correct, but too minimal for my purposes). I've made my own solution; maybe it'll help someone else.

Let's say your string is 'Version 12.34.56'. If you use '.' to split, the other answers will tend to give you '56', when maybe what you actually want is '.34.56' (i.e. everything from the first occurrence instead of the last, but OP's specific case just so happened to only have one occurrence). Perhaps you might even want 'Version 12'.

I've also written this to handle certain failures (like if null gets passed or an empty string, etc.). In those cases, the following function will return false.

Use

splitAtSearch('Version 12.34.56', '.') // Returns ['Version 12', '.34.56']

Function

/**
 * Splits string based on first result in search
 * @param {string} string - String to split
 * @param {string} search - Characters to split at
 * @return {array|false} - Strings, split at search
 *                        False on blank string or invalid type
 */
function splitAtSearch( string, search ) {
    let isValid = string !== ''              // Disallow Empty
               && typeof string === 'string' // Allow strings
               || typeof string === 'number' // Allow numbers

    if (!isValid) { return false } // Failed
    else          { string += '' } // Ensure string type

    // Search
    let searchIndex = string.indexOf(search)
    let isBlank     = (''+search) === ''
    let isFound     = searchIndex !== -1
    let noSplit     = searchIndex === 0
    let parts       = []

    // Remains whole
    if (!isFound || noSplit || isBlank) {
        parts[0] = string
    }
    // Requires splitting
    else {
        parts[0] = string.substring(0, searchIndex)
        parts[1] = string.substring(searchIndex)
    }

    return parts
}

Examples

splitAtSearch('')                      // false
splitAtSearch(true)                    // false
splitAtSearch(false)                   // false
splitAtSearch(null)                    // false
splitAtSearch(undefined)               // false
splitAtSearch(NaN)                     // ['NaN']
splitAtSearch('foobar', 'ba')          // ['foo', 'bar']
splitAtSearch('foobar', '')            // ['foobar']
splitAtSearch('foobar', 'z')           // ['foobar']
splitAtSearch('foobar', 'foo')         // ['foobar'] not ['', 'foobar']
splitAtSearch('blah bleh bluh', 'bl')  // ['blah bleh bluh']
splitAtSearch('blah bleh bluh', 'ble') // ['blah ', 'bleh bluh']
splitAtSearch('$10.99', '.')           // ['$10', '.99']
splitAtSearch(3.14159, '.')            // ['3', '.14159']
Leon Williams
  • 674
  • 1
  • 7
  • 15
3

Efficient, compact and works in the general case:

s='sometext-20202'
s.slice(s.lastIndexOf('-')+1)
Jonathan
  • 1,007
  • 16
  • 12
2

You can use split method for it. And if you should take string from specific pattern you can use split with req. exp.:

var string = "sometext-20202";
console.log(string.split(/-(.*)/)[1])
aturan23
  • 4,798
  • 4
  • 28
  • 52
  • Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. – Jeroen Steenbeeke Feb 16 '21 at 09:47
1

Use a regular expression of the form: \w-\d+ where a \w represents a word and \d represents a digit. They won't work out of the box, so play around. Try this.

dirkgently
  • 108,024
  • 16
  • 131
  • 187
0

Everyone else has posted some perfectly reasonable answers. I took a different direction. Without using split, substring, or indexOf. Works great on i.e. and firefox. Probably works on Netscape too.

Just a loop and two ifs.

function getAfterDash(str) {
    var dashed = false;
    var result = "";
    for (var i = 0, len = str.length; i < len; i++) {
        if (dashed) {
            result = result + str[i];
        }
        if (str[i] === '-') {
            dashed = true;
        }
    }
    return result;
};

console.log(getAfterDash("adfjkl-o812347"));

My solution is performant and handles edge cases.


The point of the above code was to procrastinate work, please don't actually use it.

axwr
  • 2,118
  • 1
  • 16
  • 29
0

To use any delimiter and get first or second part

  //To divide string using deimeter - here @
  //str: full string that is to be splitted
  //delimeter: like '-'
  //part number: 0 - for string befor delimiter , 1 - string after delimiter
  getPartString(str, delimter, partNumber) {
    return str.split(delimter)[partNumber];
  }
Syscall
  • 19,327
  • 10
  • 37
  • 52