3

I need to convert an alphanumeric string, which is written in camelCase to regular string. My input can be any of the following strings:

var strs = {
    input: [
        "thisStringIsGood",
        "somethingLikeThis",
        "a123CapsHere345AndHEREButNOT678Here90End",
        "123CapsHere345AndHEREButNOT678Here90e",
        "ABCAcryonym",
        "xmlHTTPRequest",
    "thisDeviceHasA3PrintingService"
    ],
    expectedResult: [
        "This String Is Good",
        "Something Like This",
        "A123 Caps Here345 And HERE But NOT678 Here90 End",
        "123 Caps Here345 And HERE But NOT678 Here90 e",
        "ABC Acryoynm",
        "Xml HTTP Request",
    "This Device Has A3 Printing Service"
    ]
};

After for converting the string into the expected format I'm doing this:

function capSplit(str) {
        return str.replace(/(^[a-z]+)|[0-9]+|[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z]|[0-9])/g, function (match, first) {
            if (first) match = match[0].toUpperCase() + match.substr(1);
            return match + ' ';
        })
    }

But the problem is that the spaces are added with the numbers as well. I need to convert string "thisDeviceHasA3Service" to be converted as "This Device Has A3 Printing Service" but the function capSplit(str) gives me This Device Has A 3 Printing Service I don't know what I'm missing. Here is the fiddle

winner_joiner
  • 12,173
  • 4
  • 36
  • 61
Hitesh Kumar
  • 3,508
  • 7
  • 40
  • 71

3 Answers3

4

This is the solution i found:

function capSplit(str) {
  return str.replace(/([A-Z][a-z])|([a-z][A-Z])|(\d[a-zA-Z])/g, function (g, m1, m2, m3) {
    return m1 ? " " + m1 : (m2 ? m2[0] + " " + m2[1] : m3[0] + " " + m3[1]);
  }).replace(/^[a-z]/g, function (g) {
    return g.toUpperCase();
  });
}

The main regexp matches every situation where a space needs to be inserted and then the function inserts the space where it's required

mck89
  • 18,918
  • 16
  • 89
  • 106
0

You can use slightly changed function from here https://stackoverflow.com/a/6229124/915194

function capSplit(str) {
    return str
    // insert a space between lower & upper
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    // insert a space between number & any letter
    .replace(/([0-9])([A-Za-z])/g, '$1 $2')
    // space before last upper in a sequence followed by lower
    .replace(/\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')
    // uppercase the first character
    .replace(/^./, function(str){ return str.toUpperCase(); })
}
Community
  • 1
  • 1
  • Why ? I tested it with your [fiddle](http://jsfiddle.net/hitesh_kumar/xh3HT/9/). Looks like all results are corresponding to expectedResult array. – Maiseyenka Dzmitry Sep 21 '15 at 10:29
  • It converts string a123CapsHere345AndHEREButNOT678Here90End-->A 123 Caps Here 345 And HERE But NOT 678 Here 90 End. A123 is converted as A 123 – Hitesh Kumar Sep 23 '15 at 05:12
0

The answer is, in the lookahead loose the |[0-9], and your code will work

function capSplit(str) {
        return str.replace(/(^[a-z]+)|[0-9]+|[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z])/g, function (match, first) {
            if (first) match = match[0].toUpperCase() + match.substr(1);
            return match + ' ';
        })
    }

here the updated jsfiddle link

winner_joiner
  • 12,173
  • 4
  • 36
  • 61