Come convertire "camelCase" in "Camel Case"?


174

Ho cercato di ottenere un comando regex JavaScript per trasformare qualcosa di simile "thisString"in "This String"ma il più vicino che ho ottenuto è la sostituzione di una lettera, risultante in qualcosa di simile "Thi String"o "This tring". Qualche idea?

Per chiarire che posso gestire la semplicità di scrivere una lettera in maiuscolo, non sono così forte con RegEx e la divisione "somethingLikeThis"in "something Like This"è dove sto avendo problemi.



6
In che modo questo è un duplicato di quello. Tutto ciò che fa è scrivere in maiuscolo il primo carattere di una stringa, nulla di simile a ciò che voglio fare.
Un mago l'ha fatto il

Hmm non è un inganno della domanda, ma il risultato potrebbe essere lo stesso. O non è quello che volevi fare? Elaborare di più?
Superfro,

Per la pratica di regex suggerisco a RegExr o Expresso di provare e basta guardare tutte le domande regex su SO e provare a rispondere. I regex non sono la cosa più semplice del mondo, ma ricorda solo che se il tuo regex ti confonde, allora dividilo e lavora in pezzi.
josh.trow,

Risposte:


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

visualizza

This String Is Good


1
Bravo uomo, dividendolo. Basta ricordarsi di Bobince consiglio: stackoverflow.com/questions/1732348/...
josh.trow

Sei sicuro che questo sia compatibile con IE? Ho appena provato in IETester7 e ho ricevuto un errore.
Strongriley,

3
Inoltre aggiungendo: se hai un acronimo tutto maiuscolo che vuoi tenere insieme, puoi cambiare la prima regex in "/ ([AZ] [az]) /"
jackfrster

2
"Questo" -> "Questo" (spazio prefisso indesiderato). Magari cambiarlo in: str.slice (0, 1) .toUpperCase () + str.slice (1) .replace (/ ([AZ]) / g, '$ 1')
Mark Vayngrib,

1
@ColdCerberus Puoi usare: str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() );si convertirà userIDin User ID, e si convertirà anche userIDFieldinUser ID Field
Eugene Mala,

87

Ho avuto un interesse ozioso in questo, in particolare nella gestione di sequenze di capitali, come in xmlHTTPRequest. Le funzioni elencate producono "Richiesta HTTP Xml" o "Richiesta HTTP Xml", la mia produce "Richiesta 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(); })
}

C'è anche una versione String.prototype in breve .


Lo stesso può essere ottenuto con 2 chiamate sostitutive:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Eugene Mala

22

Questo può essere fatto in modo conciso con regex lookahead ( live demo ):

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

(Ho pensato che il g bandiera (globale) fosse necessaria, ma stranamente, non è in questo caso particolare.)

L'uso di lookahead con splitassicura che la lettera maiuscola abbinata non venga consumata ed evita di occuparsi di uno spazio iniziale se UpperCamelCase è qualcosa di cui devi occuparti. Per scrivere in maiuscolo la prima lettera di ciascuna, puoi usare:

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

Il mapmetodo array è una funzione ES5, ma è comunque possibile utilizzarlo nei browser più vecchi con un po 'di codice da MDC . In alternativa, è possibile scorrere gli elementi dell'array utilizzando un forciclo.


La prima funzione la divide, ma non PascalCase la prima parola. La seconda funzione ha esito negativo in un caso nessuno cammellato. (es: 'id')
Dementic

16

Penso che questo dovrebbe essere in grado di gestire caratteri maiuscoli consecutivi e semplici camelCase.

Ad esempio: someVariable => someVariable, ma ABCCode! = Codice ABC.

Il regex di seguito funziona sul tuo esempio ma anche sull'esempio comune di rappresentazione delle abbreviazioni in 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"

Puoi anche regolare come sopra per capitalizzare il primo personaggio.


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

spacecamel ( '') somethingLikeThis

// valore restituito: qualcosa del genere


1
Ben fatto! questo è esattamente ciò di cui avevo bisogno che volevo dividere, ad esempio: DiscoveryChannel e HBO altre risposte mi hanno dato Discovery Channel e HBO, ma la tua risposta ha funzionato per me poiché HBO è rimasto intatto grazie!
AJS,


4

Una soluzione che gestisce anche i numeri:

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

Testato qui [JSFiddle, nessuna libreria. Non provato IE]; dovrebbe essere abbastanza stabile.


0

Se non ti interessano i browser più vecchi (o non ti dispiace usare una funzione di riduzione del fallback per loro), questo può dividere anche stringhe come 'xmlHTTPRequest' (ma certamente cose del genere di 'XMLHTTPRequest' non possono).

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

La mia versione

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"

Ho applicato questa funzione in loop su 3000 linee e ho ottenuto quegli spazi davanti a ogni linea che inizia con la capitale
Dominik Domanski,

0

Prova questa soluzione qui -

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

Non regex, ma utile per conoscere tecniche semplici e vecchie come questa:

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

5
no, la domanda è "thisString" a "This String" (con uno spazio) non "ThisString"
Pete Kirkham,

@rob Come si inserisce uno spazio tra "this" e "String"?
ThunderBird,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.