Convertir guiones a camel case (camelCase)

146

Con regex (supongo) o algún otro método, ¿cómo puedo convertir cosas como:

marker-imageo my-example-settinga markerImageo myExampleSetting.

Estaba pensando en dividir para -luego convertir el índice de ese hypen +1 a mayúsculas. Pero parece bastante sucio y esperaba ayuda con expresiones regulares que podría hacer que el código fuera más limpio.

No jQuery ...

Oscar Godson
fuente
1
Duplicado exacto de JavaScript RegExp $ 1 a mayúscula
mplungjan
77
en realidad lo es, pero busqué y nunca lo encontré probablemente debido al nombre oscuro. Sugeriría mantener esto abierto para que las personas puedan encontrar la respuesta. "RegExp $ 1 en mayúsculas" ... nadie lo va a encontrar a menos que ya conozcan regex IMO
Oscar Godson
Eso fue fácilmente reparable. Acabo de editar el título
mplungjan
Entonces, cortar y pegar las soluciones me habría valido una respuesta aceptada: |
mplungjan
¿Hay alguna manera de hacer exactamente lo contrario?
Pavan

Respuestas:

258

Prueba esto:

var camelCased = myString.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });

La expresión regular coincidirá con el -ide marker-imagey la captura sólo el i. Esto se pone en mayúscula en la función de devolución de llamada y se reemplaza.

Paolo Moretti
fuente
53
FYI, aquí está lo contrario:myString.replace(/([a-z][A-Z])/g, function (g) { return g[0] + '-' + g[1].toLowerCase() });
Cyril N.
Creo que el parámetro debe renombrarse a "m", como "partido". Uno puede escribir rápidamente algo como: myString.replace(/-([a-z])/i, function (i) { return i[1].toUpperCase() });
programaths
8
Sería una buena idea hacer que su expresión regular sea más sólida agregando la ibandera. Sin él, su patrón pierde "Partes capitalizadas" (no se cambiará a "Partes capitalizadas"). Además, personalmente prefiero la legibilidad mejorada de múltiples parámetros, pero eso es obviamente una cuestión de estilo. Con todo, iría con .replace( /-([a-z])/gi, function ( $0, $1 ) { return $1.toUpperCase(); } );.
hashchange
Para agregar a esto, si desea var camelCased = myString.replace(/(-+|\s+)\w/g, function (g) { return g[1].toUpperCase(); });
camelizar
@ wolfram77, incluye varios guiones / caracteres de espacio en la expresión regular, luego en mayúscula el segundo carácter de la coincidencia, lo que significa que si el segundo carácter es un espacio o guión, es el que se pone en mayúscula. ¿Qué tal esto var camelCased = myString.replace(/(-+|\s+)\w/g, function (g) { return g[g.length - 1].toUpperCase(); });?
trysis
44

Esta es una de las grandes utilidades que ofrece Lodash si está iluminado y lo incluye en su proyecto.

var str = 'my-hyphen-string';
str = _.camelCase(str);
// results in 'myHyphenString'
ShadeTreeDeveloper
fuente
14

Puedes obtener el himno y el siguiente personaje y reemplazarlo con la versión en mayúsculas del personaje:

var str="marker-image-test";
str.replace(/-([a-z])/g, function (m, w) {
    return w.toUpperCase();
});
mck89
fuente
3
Agradable: utilicé este método, pero ES6 lo introduje en >> str.replace (/ - ([az]) / g, (x, up) => up.toUpperCase ())
ConorLuddy el
13

Aquí está mi versión de la función camelCase:

var camelCase = (function () {
    var DEFAULT_REGEX = /[-_]+(.)?/g;

    function toUpper(match, group1) {
        return group1 ? group1.toUpperCase() : '';
    }
    return function (str, delimiters) {
        return str.replace(delimiters ? new RegExp('[' + delimiters + ']+(.)?', 'g') : DEFAULT_REGEX, toUpper);
    };
})();

Maneja todos los siguientes casos límite:

  • se encarga de los guiones bajos y guiones de forma predeterminada (configurable con el segundo parámetro)
  • cadena con caracteres unicode
  • cadena que termina con guiones o guiones bajos
  • cadena que tiene guiones o guiones bajos consecutivos

Aquí hay un enlace a las pruebas en vivo: http://jsfiddle.net/avKzf/2/

Aquí están los resultados de las pruebas:

  • entrada: "ab-cd-ef", resultado: "abCdEf"
  • entrada: "ab-cd-ef-", resultado: "abCdEf"
  • entrada: "ab-cd-ef--", resultado: "abCdEf"
  • entrada: "ab-cd - ef--", resultado: "abCdEf"
  • entrada: "--ab-cd - ef--", resultado: "AbCdEf"
  • entrada: "--ab-cd -__- ef--", resultado: "AbCdEf"

Observe que las cadenas que comienzan con delimitadores darán como resultado una letra mayúscula al principio. Si eso no es lo que esperarías, siempre puedes usar lcfirst. Aquí está mi primer mensaje si lo necesita:

function lcfirst(str) {
    return str && str.charAt(0).toLowerCase() + str.substring(1);
}
Joon
fuente
4

Esto no es un grito para RegExpmí. Personalmente, trato de evitar expresiones regulares cuando una cadena simple y métodos de matriz son suficientes:

let upFirst = word => 
  word[0].toUpperCase() + word.toLowerCase().slice(1)

let camelize = text => {
  let words = text.split(/[-_]/g) // ok one simple regexp.
  return words[0].toLowerCase() + words.slice(1).map(upFirst)
}

camelize('marker-image') // markerImage

fuente
1

Aquí hay otra opción que combina un par de respuestas aquí y hace que sea un método en una cadena:

if (typeof String.prototype.toCamel !== 'function') {
  String.prototype.toCamel = function(){
    return this.replace(/[-_]([a-z])/g, function (g) { return g[1].toUpperCase(); })
  };
}

Usado así:

'quick_brown'.toCamel(); // quickBrown
'quick-brown'.toCamel(); // quickBrown
John Naegle
fuente
1
// Turn the dash separated variable name into camelCase.
str = str.replace(/\b-([a-z])/g, (_, char) => char.toUpperCase());
alex
fuente
1

Puedes usar camelcase de NPM.

npm install --save camelcase

const camelCase = require('camelcase');
camelCase('marker-image'); // => 'markerImage';
camelCase('my-example-setting'); // => 'myExampleSetting';
Lanil Marasinghe
fuente
0

Otra toma

Usado cuando ...

var string = "hyphen-delimited-to-camel-case"
or
var string = "snake_case_to_camel_case"


function toCamelCase( string ){
  return string.toLowerCase().replace(/(_|-)([a-z])/g, toUpperCase );
}

function toUpperCase( string ){
  return string[1].toUpperCase();
}

Output: hyphenDelimitedToCamelCase
SoEzPz
fuente
0

También es posible usar indexOf con recursividad para esa tarea.

input some-foo_sd_dsd-weqe
output someFooSdDsdWeqe

comparación ::: medir el tiempo de ejecución para dos scripts diferentes:

$ node camelCased.js
someFooSdDsdWeqe
test1: 2.986ms
someFooSdDsdWeqe
test2: 0.231ms

código:

console.time('test1');
function camelCased (str) {

        function check(symb){

            let idxOf = str.indexOf(symb);
            if (idxOf === -1) {
                return str;
            }

            let letter = str[idxOf+1].toUpperCase();
            str = str.replace(str.substring(idxOf+1,idxOf+2), '');
            str = str.split(symb).join(idxOf !== -1 ? letter : '');

            return camelCased(str);
        }       

        return check('_') && check('-');

    }

console.log(camelCased ('some-foo_sd_dsd-weqe'));
console.timeEnd('test1');



console.time('test2');

    function camelCased (myString){
     return myString.replace(/(-|\_)([a-z])/g, function (g) { return  g[1].toUpperCase(); });
   }


console.log(camelCased ('some-foo_sd_dsd-weqe'));
console.timeEnd('test2');
Anja Ishmukhametova
fuente
0

Solo una versión con bandera, para loop y sin Regex:

function camelCase(dash) { 

  var camel = false;
  var str = dash;
  var camelString = '';

  for(var i = 0; i < str.length; i++){
    if(str.charAt(i) === '-'){
      camel = true;

    } else if(camel) {
      camelString += str.charAt(i).toUpperCase();
      camel = false;
    } else {
      camelString += str.charAt(i);
    }
  } 
  return camelString;
}
Cazador
fuente
0

Aquí está mi implementación (solo para ensuciarse las manos)

/**
 * kebab-case to UpperCamelCase
 * @param {String} string
 * @return {String}
 */
function toUpperCamelCase(string) {
  return string
    .toLowerCase()
    .split('-')
    .map(it => it.charAt(0).toUpperCase() + it.substr(1))
    .join('');
}
D.Dimitrioglo
fuente
0

Use esto si permite números en su cadena.

Obviamente, las partes que comienzan con un número no se capitalizarán, pero esto puede ser útil en algunas situaciones.

function fromHyphenToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase())
}

function fromHyphenToCamelCase(str) {
  return str.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase())
}

const str1 = "category-123";
const str2 = "111-222";
const str3 = "a1a-b2b";
const str4 = "aaa-2bb";

console.log(`${str1} => ${fromHyphenToCamelCase(str1)}`);
console.log(`${str2} => ${fromHyphenToCamelCase(str2)}`);
console.log(`${str3} => ${fromHyphenToCamelCase(str3)}`);
console.log(`${str4} => ${fromHyphenToCamelCase(str4)}`);

cbdeveloper
fuente