¿Cómo convertir "camelCase" a "Camel Case"?


174

He estado tratando de conseguir una orden de expresiones regulares JavaScript para convertir algo así como "thisString"en "This String"pero lo más cerca que he recibido está reemplazando una carta, lo que resulta en algo así como "Thi String"o "This tring". ¿Algunas ideas?

Para aclarar que puedo manejar la simplicidad de la capitalización de una carta, simplemente no lo soy fuerte con expresiones regulares, y la división "somethingLikeThis"en "something Like This"es donde estoy teniendo problemas.



66
¿Cómo es esto un duplicado de eso? Todo lo que hace es poner en mayúscula el primer carácter de una cadena, nada parecido a lo que quiero hacer.
Un mago lo hizo

Hmm no es un engaño de la pregunta, pero el resultado podría ser el mismo. ¿O no es eso lo que querías hacer? ¿Elaborar más?
Superfro

Para la práctica de expresiones regulares, sugiero que RegExr o Expresso se prueben y solo miren todas las preguntas de expresiones regulares en SO e intenten responderlas. Las expresiones regulares no son la cosa más simple del mundo, pero recuerda que si tu expresión regular te confunde, entonces divídela y trabaja en pedazos.
josh.trow

Respuestas:


399
"thisStringIsGood"
    // insert a space before all caps
    .replace(/([A-Z])/g, ' $1')
    // uppercase the first character
    .replace(/^./, function(str){ return str.toUpperCase(); })

muestra

This String Is Good


1
Buen hombre, dividiéndolo. Solo recuerde el consejo de Bobince: stackoverflow.com/questions/1732348/…
josh.trow

¿Estás seguro de que esto es compatible con IE? Acabo de probar en IETester7 y recibí un error.
strongriley

3
También agrega: si tiene un acrónimo de mayúsculas que desea mantener juntos, puede cambiar la primera expresión regular a "/ ([AZ] [az]) /"
jackfrster

2
"This" -> "This" (espacio de prefijo no deseado). Tal vez cámbielo a: str.slice (0, 1) .toUpperCase () + str.slice (1) .replace (/ ([AZ]) / g, '$ 1')
Mark Vayngrib

1
@ColdCerberus Puede usar: str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() );Se convertirá userIDa User ID, e incluso se convertirá userIDFieldaUser ID Field
Eugene Mala

87

Tenía un interés inactivo en esto, particularmente en el manejo de secuencias de mayúsculas, como en xmlHTTPRequest. Las funciones enumeradas producirían "Solicitud HTTP Xml" o "Solicitud HTTP Xml", la mía produce "Solicitud HTTP Xml".

function unCamelCase (str){
    return str
        // insert a space between lower & upper
        .replace(/([a-z])([A-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(); })
}

También hay una versión de String.prototype en una esencia .


Lo mismo se puede lograr con 2 llamadas de reemplazo:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Eugene Mala

22

Esto se puede hacer de manera concisa con regex lookahead ( demostración en vivo ):

function splitCamelCaseToString(s) {
    return s.split(/(?=[A-Z])/).join(' ');
}

(Pensé que la gbandera (global) era necesaria, pero curiosamente, no lo es en este caso particular).

Usar lookahead con splitasegura que la letra mayúscula coincidente no se consuma y evita tratar con un espacio inicial si UpperCamelCase es algo con lo que debe lidiar. Para poner en mayúscula la primera letra de cada uno, puede usar:

function splitCamelCaseToString(s) {
    return s.split(/(?=[A-Z])/).map(function(p) {
        return p.charAt(0).toUpperCase() + p.slice(1);
    }).join(' ');
}

El mapmétodo de matriz es una característica de ES5, pero aún puede usarlo en navegadores antiguos con algún código de MDC . Alternativamente, puede iterar sobre los elementos de la matriz utilizando un forbucle.


La primera función la divide, pero no PascalCase la primera palabra. La segunda función falla en un caso sin camelCased. (p. ej .: 'id')
Demencial

16

Creo que esto debería ser capaz de manejar caracteres en mayúsculas consecutivos, así como camelCase simple.

Por ejemplo: someVariable => someVariable, pero ABCCode! = Código ABC.

La expresión regular a continuación funciona en su ejemplo, pero también en el ejemplo común de representar abreviaturas en camcelCase.

"somethingLikeThis"
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/([A-Z])([a-z])/g, ' $1$2')
    .replace(/\ +/g, ' ') => "something Like This"

"someVariableWithABCCode"
    .replace(/([a-z])([A-Z])/g, '$1 $2')
    .replace(/([A-Z])([a-z])/g, ' $1$2')
    .replace(/\ +/g, ' ') => "some Variable With ABC Code"

También puede ajustar como se indica arriba para capitalizar el primer carácter.


10
function spacecamel(s){
    return s.replace(/([a-z])([A-Z])/g, '$1 $2');
}

spacecamel ('algo como esto')

// valor devuelto: algo como esto


1
¡Buena esa! esto es exactamente lo que necesitaba que quería dividir, por ejemplo: DiscoveryChannel y HBO, otras respuestas me dieron Discovery Channel y HBO, pero su respuesta me funcionó, ya que HBO se mantuvo intacto, ¡gracias!
AJS


4

Una solución que también maneja números:

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 + ' ';
          }
       )
   }

Probado aquí [JSFiddle, no library. No probé IE]; Debería ser bastante estable.


0

Si no le interesan los navegadores más antiguos (o no le importa usar una función de reducción de reserva para ellos), esto puede dividir incluso cadenas como 'xmlHTTPRequest' (pero ciertamente no puede hacerlo 'XMLHTTPRequest').

function splitCamelCase(str) {
        return str.split(/(?=[A-Z])/)
                  .reduce(function(p, c, i) {
                    if (c.length === 1) {
                        if (i === 0) {
                            p.push(c);
                        } else {
                            var last = p.pop(), ending = last.slice(-1);
                            if (ending === ending.toLowerCase()) {
                                p.push(last);
                                p.push(c);
                            } else {
                                p.push(last + c);
                            }
                        }
                    } else {
                        p.push(c.charAt(0).toUpperCase() + c.slice(1));
                    }
                    return p;
                  }, [])
                  .join(' ');
}

0

Mi version

function camelToSpace (txt) {
  return txt
    .replace(/([^A-Z]*)([A-Z]*)([A-Z])([^A-Z]*)/g, '$1 $2 $3$4')
    .replace(/ +/g, ' ')
}
camelToSpace("camelToSpaceWithTLAStuff") //=> "camel To Space With TLA Stuff"

Apliqué esta función en bucle en 3000 líneas, y obtuve esos espacios delante de cada línea que comienza con mayúscula
Dominik Domanski

0

Prueba esta solución aquí:

var value = "myCamelCaseText";
var newStr = '';
for (var i = 0; i < value.length; i++) {
  if (value.charAt(i) === value.charAt(i).toUpperCase()) {
    newStr = newStr + ' ' + value.charAt(i)
  } else {
    (i == 0) ? (newStr += value.charAt(i).toUpperCase()) : (newStr += value.charAt(i));
  }
}
return newStr;

-5

No es una expresión regular, pero es útil para conocer técnicas simples y antiguas como esta:

var origString = "thisString";
var newString = origString.charAt(0).toUpperCase() + origString.substring(1);

55
no, la pregunta es "thisString" a "This String" (con un espacio) no "ThisString"
Pete Kirkham

@rob ¿Cómo poner un espacio entre "esto" y "Cadena"?
ThunderBird
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.