Convertir camelCaseText en texte de casse de phrase

145

Comment puis-je convertir une chaîne comme «helloThere» ou «HelloThere» en «Hello There» en JavaScript?

HyderA
la source
9
hmm .. quelle est votre sortie attendue pour iLiveInTheUSA?
wim
8
Je vis dans le U ... oh merde! - Mais dans mon cas, j'ai un ensemble limité de chaînes et aucune chaîne de ce type ne pourrait casser un simple convertisseur. Bonne prise cependant!
HyderA
De même, uSBPort devrait aboutir à un «port USB»
signonsridhar
2
@wim: iLiveInTheUSA devrait être iLiveInTheUsa dans la notation correcte de la casse de chameau, mais cela présenterait des problèmes différents.
Konrad Höffner

Réponses:

188
var text = 'helloThereMister';
var result = text.replace( /([A-Z])/g, " $1" );
var finalResult = result.charAt(0).toUpperCase() + result.slice(1);
console.log(finalResult);

mettre en majuscule la première lettre - à titre d'exemple.

Notez l'espace dans " $1".

EDIT: ajout d'un exemple de capitalisation de la première lettre. Bien sûr, au cas où la première lettre serait déjà en majuscule, vous auriez un espace libre à supprimer.

ZenMaster
la source
1
Je creuse l'utilisation d'espaces dans text.replace, j'ai complété les appels de fonction avec plus de 2 arguments avec des espaces pour la lisibilité aussi
rkd
8
uSBPorts => Ports USB, pas ce à quoi je m'attends, je veux des ports USB
signonsridhar
qu'en est-il de l'écriture Non-GoogleChrome?
tim
107

Alternativement en utilisant lodash :

lodash.startCase(str);

Exemple:

_.startCase('helloThere');
// ➜ 'Hello There'

Lodash est une bonne bibliothèque pour donner un raccourci vers de nombreuses tâches quotidiennes de js.Il existe de nombreuses autres fonctions de manipulation de chaînes similaires telles que camelCase, kebabCaseetc.

Wtower
la source
Si vous essayez hello worldalors la sortie devrait être Hello There, Dans ce cas, loadash ne sera pas utile.
Abhishek Kumar
@AbhishekKumar startCase of lodash sera effectivement converti hello worlden Hello World lodash.com/docs/4.17.15#upperFirst
user1696017 le
Tu as raison frère. Par erreur, j'ai écrit hello thereà hello world.
Abhishek Kumar le
2
Chaque fois que je pense "il n'y a aucun moyen pour que lodash fasse ça aussi", c'est le cas.
efru
Attention à partir de la v4, cette fonction supprime les caractères spéciaux comme ä et les convertit en caractères ASCII (a dans ce cas)
Collerek
52

J'ai eu un problème similaire et je l'ai traité comme ceci:

stringValue.replace(/([A-Z]+)*([A-Z][a-z])/g, "$1 $2")

Pour une solution plus robuste:

stringValue.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1")

http://jsfiddle.net/PeYYQ/

Contribution:

 helloThere 
 HelloThere 
 ILoveTheUSA
 iLoveTheUSA

Production:

 hello There 
 Hello There 
 I Love The USA
 i Love The USA
James Khoury
la source
il met un espace supplémentaire au départ
hannad rehman
4
Ce n'est pas un cas de phrase comme OP l'a demandé. La première lettre doit être en majuscule.
H Dog
De plus, il ajoute un espace supplémentaire entre les mots
Alacritas
34

Exemple sans effets secondaires.

function camel2title(camelCase) {
  // no side-effects
  return camelCase
    // inject space before the upper case letters
    .replace(/([A-Z])/g, function(match) {
       return " " + match;
    })
    // replace first char with upper case
    .replace(/^./, function(match) {
      return match.toUpperCase();
    });
}

Dans ES6

const camel2title = (camelCase) => camelCase
  .replace(/([A-Z])/g, (match) => ` ${match}`)
  .replace(/^./, (match) => match.toUpperCase());
Renevanderark
la source
1
Solide, +1 pour l'extrait es6.
BradStell
4
FYI, cela ajoute des espaces supplémentaires au début de la phrase.
Dale Zak
20

La meilleure chaîne que j'ai trouvée pour tester les fonctions camel-case-to-title-case est cet exemple ridiculement absurde, qui teste de nombreux cas extrêmes. À ma connaissance, aucune des fonctions précédemment publiées ne gère cela correctement :

PourGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D

Cela doit être converti en:

Pour obtenir votre GED à temps, une chanson sur les 26 ABC est essentielle, mais une carte d'identité personnelle pour l'utilisateur 456 dans la salle 26A contenant 26 fois ABC n'est pas aussi simple que 123 pour C3PO ou R2D2 ou 2R2D

Si vous voulez juste une fonction simple qui gère des cas comme celui ci-dessus (et plus de cas que la plupart des réponses précédentes), voici celui que j'ai écrit. Ce code n'est ni particulièrement élégant ni rapide, mais il est simple, compréhensible et fonctionne.

Un exemple exécutable en ligne est sur jsfiddle , ou vous pouvez afficher la sortie de l'extrait ci-dessous dans votre console:

// Take a single camel case string and convert it to a string of separate words (with spaces) at the camel-case boundaries.
// 
// E.g.:
var examples = [
    'ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D',
    //                                          --> To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D
    'helloThere', //                              --> Hello There
    'HelloThere', //                              --> Hello There
    'ILoveTheUSA', //                             --> I Love The USA
    'iLoveTheUSA', //                             --> I Love The USA
    'DBHostCountry', //                           --> DB Host Country
    'SetSlot123ToInput456', //                    --> Set Slot 123 To Input 456
    'ILoveTheUSANetworkInTheUSA', //              --> I Love The USA Network In The USA
    'Limit_IOC_Duration', //                      --> Limit IOC Duration
    'This_is_a_Test_of_Network123_in_12_days', // --> This Is A Test Of Network 123 In 12 Days
    'ASongAboutTheABCsIsFunToSing', //            --> A Song About The ABCs Is Fun To Sing
    'CFDs', //                                    --> CFDs
    'DBSettings', //                              --> DB Settings
    'IWouldLove1Apple', //                        --> 1 Would Love 1 Apple
    'Employee22IsCool', //                        --> Employee 22 Is Cool
    'SubIDIn', //                                 --> Sub ID In
    'ConfigureCFDsImmediately', //                --> Configure CFDs Immediately
    'UseTakerLoginForOnBehalfOfSubIDInOrders', // --> Use Taker Login For On Behalf Of Sub ID In Orders
]

function camelCaseToTitleCase(in_camelCaseString) {
        var result = in_camelCaseString                         // "ToGetYourGEDInTimeASongAboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser456InRoom26AContainingABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D"
            .replace(/([a-z])([A-Z][a-z])/g, "$1 $2")           // "To Get YourGEDIn TimeASong About The26ABCs IsOf The Essence ButAPersonalIDCard For User456In Room26AContainingABC26Times IsNot AsEasy As123ForC3POOrR2D2Or2R2D"
            .replace(/([A-Z][a-z])([A-Z])/g, "$1 $2")           // "To Get YourGEDIn TimeASong About The26ABCs Is Of The Essence ButAPersonalIDCard For User456In Room26AContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([a-z])([A-Z]+[a-z])/g, "$1 $2")          // "To Get Your GEDIn Time ASong About The26ABCs Is Of The Essence But APersonal IDCard For User456In Room26AContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([A-Z]+)([A-Z][a-z][a-z])/g, "$1 $2")     // "To Get Your GEDIn Time A Song About The26ABCs Is Of The Essence But A Personal ID Card For User456In Room26A ContainingABC26Times Is Not As Easy As123ForC3POOr R2D2Or2R2D"
            .replace(/([a-z]+)([A-Z0-9]+)/g, "$1 $2")           // "To Get Your GEDIn Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC26Times Is Not As Easy As 123For C3POOr R2D2Or 2R2D"
            
            // Note: the next regex includes a special case to exclude plurals of acronyms, e.g. "ABCs"
            .replace(/([A-Z]+)([A-Z][a-rt-z][a-z]*)/g, "$1 $2") // "To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC26Times Is Not As Easy As 123For C3PO Or R2D2Or 2R2D"
            .replace(/([0-9])([A-Z][a-z]+)/g, "$1 $2")          // "To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456In Room 26A Containing ABC 26Times Is Not As Easy As 123For C3PO Or R2D2Or 2R2D"  

            // Note: the next two regexes use {2,} instead of + to add space on phrases like Room26A and 26ABCs but not on phrases like R2D2 and C3PO"
            .replace(/([A-Z]{2,})([0-9]{2,})/g, "$1 $2")        // "To Get Your GED In Time A Song About The 26ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
            .replace(/([0-9]{2,})([A-Z]{2,})/g, "$1 $2")        // "To Get Your GED In Time A Song About The 26 ABCs Is Of The Essence But A Personal ID Card For User 456 In Room 26A Containing ABC 26 Times Is Not As Easy As 123 For C3PO Or R2D2 Or 2R2D"
            .trim();


  // capitalize the first letter
  return result.charAt(0).toUpperCase() + result.slice(1);
}

examples.forEach(str => console.log(str, ' --> \n', camelCaseToTitleCase(str)));

Chris Kline
la source
11

Sur la base de l'un des exemples ci-dessus, j'ai trouvé ceci:

const camelToTitle = (camelCase) => camelCase
  .replace(/([A-Z])/g, (match) => ` ${match}`)
  .replace(/^./, (match) => match.toUpperCase())
  .trim()

Cela fonctionne pour moi car il utilise .trim()pour gérer le cas de bord où la première lettre est en majuscule et vous vous retrouvez avec un espace de début supplémentaire.

Référence: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim

Anthony S.
la source
10

Ok, j'ai quelques années de retard dans le jeu, mais j'avais une question similaire, et je voulais faire une solution de remplacement unique pour chaque entrée possible. Je dois donner l'essentiel du crédit à @ZenMaster dans ce fil et à @Benjamin Udink ten Cate dans ce fil. Voici le code:

var camelEdges = /([A-Z](?=[A-Z][a-z])|[^A-Z](?=[A-Z])|[a-zA-Z](?=[^a-zA-Z]))/g;
var textArray = ["lowercase",
                 "Class",
                 "MyClass",
                 "HTML",
                 "PDFLoader",
                 "AString",
                 "SimpleXMLParser",
                 "GL11Version",
                 "99Bottles",
                 "May5",
                 "BFG9000"];
var text;
var resultArray = [];
for (var i = 0; i < a.length; i++){
    text = a[i];
    text = text.replace(camelEdges,'$1 ');
    text = text.charAt(0).toUpperCase() + text.slice(1);
    resultArray.push(text);
}

Il comporte trois clauses, toutes utilisant lookahead pour empêcher le moteur regex de consommer trop de caractères:

  1. [A-Z](?=[A-Z][a-z])recherche une lettre majuscule suivie d'une majuscule puis d'une minuscule. Il s'agit de mettre fin aux acronymes comme USA.
  2. [^A-Z](?=[A-Z])recherche une lettre non majuscule suivie d'une majuscule. Cela met fin aux mots comme myWord et aux symboles comme 99Bottles.
  3. [a-zA-Z](?=[^a-zA-Z])recherche une lettre suivie d'une non-lettre. Cela termine les mots avant les symboles comme BFG9000.

Cette question était en haut de mes résultats de recherche, alors j'espère pouvoir en faire gagner du temps à d'autres!

Christopher Smith
la source
9

Voici ma version de celui-ci. Il ajoute un espace avant chaque lettre anglaise Majuscule qui vient après une lettre anglaise minuscule et met également en majuscule la première lettre si nécessaire:

Par exemple:
thisIsCamelCase -> This Is Camel Case
this IsCamelCase -> This Is Camel Case
thisIsCamelCase123 -> This Is Camel Case123

  function camelCaseToTitleCase(camelCase){
    if (camelCase == null || camelCase == "") {
      return camelCase;
    }

    camelCase = camelCase.trim();
    var newText = "";
    for (var i = 0; i < camelCase.length; i++) {
      if (/[A-Z]/.test(camelCase[i])
          && i != 0
          && /[a-z]/.test(camelCase[i-1])) {
        newText += " ";
      }
      if (i == 0 && /[a-z]/.test(camelCase[i]))
      {
        newText += camelCase[i].toUpperCase();
      } else {
        newText += camelCase[i];
      }
    }

    return newText;
  }
asafd
la source
6

Cette implémentation prend en compte les lettres majuscules et les chiffres consécutifs.

function camelToTitleCase(str) {
  return str
    .replace(/[0-9]{2,}/g, match => ` ${match} `)
    .replace(/[^A-Z0-9][A-Z]/g, match => `${match[0]} ${match[1]}`)
    .replace(/[A-Z][A-Z][^A-Z0-9]/g, match => `${match[0]} ${match[1]}${match[2]}`)
    .replace(/[ ]{2,}/g, match => ' ')
    .replace(/\s./g, match => match.toUpperCase())
    .replace(/^./, match => match.toUpperCase())
    .trim();
}

// ----------------------------------------------------- //

var testSet = [
    'camelCase',
    'camelTOPCase',
    'aP2PConnection',
    'superSimpleExample',
    'aGoodIPAddress',
    'goodNumber90text',
    'bad132Number90text',
];

testSet.forEach(function(item) {
    console.log(item, '->', camelToTitleCase(item));
});

Production attendue:

camelCase -> Camel Case
camelTOPCase -> Camel TOP Case
aP2PConnection -> A P2P Connection
superSimpleExample -> Super Simple Example
aGoodIPAddress -> A Good IP Address
goodNumber90text -> Good Number 90 Text
bad132Number90text -> Bad 132 Number 90 Text
Dipu
la source
J'utiliserais la réponse de Chris Kline qui accepte des chaînes comme "IP Address" (où cette fonction la transforme en "IP Address"
John Hamm
@JohnHamm Votre entrée est "Adresse IP", non? Ce n'est pas une affaire de chameau! Découvrez ce qu'est le cas de chameau ici: en.wikipedia.org/wiki/Camel_case Ne pas mettre d'espace entre et saisir uniquement "IPAddress". Cette fonction fonctionne très bien.
Dipu le
3

Vous pouvez utiliser une fonction comme celle-ci:

function fixStr(str) {
    var out = str.replace(/^\s*/, "");  // strip leading spaces
    out = out.replace(/^[a-z]|[^\s][A-Z]/g, function(str, offset) {
        if (offset == 0) {
            return(str.toUpperCase());
        } else {
            return(str.substr(0,1) + " " + str.substr(1).toUpperCase());
        }
    });
    return(out);
}

"hello World" ==> "Hello World"
"HelloWorld" ==> "Hello World"
"FunInTheSun" ==? "Fun In The Sun"

Code avec un tas de chaînes de test ici: http://jsfiddle.net/jfriend00/FWLuV/ .

Version alternative qui garde les espaces de premier plan ici: http://jsfiddle.net/jfriend00/Uy2ac/ .

jfriend00
la source
Je sais que ce n'était pas une exigence dans la question, mais votre solution ne fonctionne pas " helloWorld", par exemple.
ZenMaster
Oui, c'est une nouvelle exigence. J'ai essayé de faire exactement ce que vous aviez initialement demandé. Quoi qu'il en soit, le raccourci est facile de prévoir des espaces de début si vous n'en avez pas besoin de toute façon. Si vous vouliez les laisser en place, cela pourrait être fait également.
jfriend00
Voici un jsFiddle qui montre une méthode qui fonctionne avec le nouveau require de "helloWorld" et conserve l'espace de début (si vous le souhaitez): jsfiddle.net/jfriend00/Uy2ac .
jfriend00
Agréable. Je m'interroge cependant sur les performances de celui-ci. La fonction de gestionnaire sera appelée à chaque correspondance, n'est-ce pas?
ZenMaster
Si vous en faites un million dans un cadre sensible aux performances, il faudrait un test jsperf dans un tas de navigateurs pour voir quelle serait la solution la plus rapide. Appeler un rappel n'est pas un problème. Les expressions régulières, de quelque nature que ce soit, sont rarement la solution la plus rapide par rapport au code à usage spécial, mais elles économisent beaucoup de code (et souvent des bogues) sont donc souvent le choix souhaité. Cela dépend de vos besoins.
jfriend00
3

essayez cette bibliothèque

http://sugarjs.com/api/String/titleize

'man from the boondocks'.titleize()>"Man from the Boondocks"
'x-men: the last stand'.titleize()>"X Men: The Last Stand"
'TheManWithoutAPast'.titleize()>"The Man Without a Past"
'raiders_of_the_lost_ark'.titleize()>"Raiders of the Lost Ark"
Barno
la source
2

Aucune des réponses ci-dessus ne fonctionnait parfaitement pour moi, je devais donc venir avec votre propre vélo:

function camelCaseToTitle(camelCase) {
    if (!camelCase) {
        return '';
    }

    var pascalCase = camelCase.charAt(0).toUpperCase() + camelCase.substr(1);
    return pascalCase
        .replace(/([a-z])([A-Z])/g, '$1 $2')
        .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')
        .replace(/([a-z])([0-9])/gi, '$1 $2')
        .replace(/([0-9])([a-z])/gi, '$1 $2');
}

Cas de test:

null => ''
'' => ''
'simpleString' => 'Simple String'
'stringWithABBREVIATIONInside => 'String With ABBREVIATION Inside'
'stringWithNumber123' => 'String With Number 123'
'complexExampleWith123ABBR890Etc' => 'Complex Example With 123 ABBR 890 Etc'
Vitaliy Ulantikov
la source
2

Cela fonctionne pour moi, vérifiez ceci

CamelcaseToWord ("MonNom"); // renvoie mon nom

    function CamelcaseToWord(string){
      return string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1");
    }
Poorna Rao
la source
1
Bienvenue dans SO :) Veuillez ajouter au moins une ligne explicative à votre code. Assurez-vous également qu'il s'agit de votre travail intellectuel ou citez la ou les sources.
Lorenz Lo Sauer
Vous devez supprimer l'espace dans un lat un "$ 1". string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, "$1");
Valeria Shpiner le
2

Je pense que cela peut être fait simplement avec l'exp reg /([a-z]|[A-Z]+)([A-Z])/get le remplacement "$1 $2".

ILoveTheUSADope -> I Love The USA Dope

Miguel Enrique León Figueras
la source
Pas exactement, pour la chaîne, QWERTYil retourne QWERT Y.
itachi le
2

Si vous traitez avec Capital Camel Case, cet extrait de code peut vous aider, il contient également des spécifications afin que vous puissiez être sûr qu'il correspond à votre cas.

export const fromCamelCaseToSentence = (word) =>
  word
    .replace(/([A-Z][a-z]+)/g, ' $1')
    .replace(/([A-Z]{2,})/g, ' $1')
    .replace(/\s{2,}/g, ' ')
    .trim();

Et spécifications:

describe('fromCamelCaseToSentence', () => {
 test('does not fall with a single word', () => {
   expect(fromCamelCaseToSentence('Approved')).toContain('Approved')
   expect(fromCamelCaseToSentence('MDA')).toContain('MDA')
 })

 test('does not fall with an empty string', () => {
   expect(fromCamelCaseToSentence('')).toContain('')
 })

 test('returns the separated by space words', () => {
   expect(fromCamelCaseToSentence('NotApprovedStatus')).toContain('Not Approved Status')
   expect(fromCamelCaseToSentence('GDBState')).toContain('GDB State')
   expect(fromCamelCaseToSentence('StatusDGG')).toContain('Status DGG')
 })
})
Purkhalo Alex
la source
1

Je n'ai pas essayé la réponse de tout le monde, mais les quelques solutions que j'ai bricolées ne correspondaient pas à toutes mes exigences.

J'ai pu trouver quelque chose qui a fait ...

export const jsObjToCSSString = (o={}) =>
    Object.keys(o)
          .map(key => ({ key, value: o[key] }))
          .map(({key, value}) =>
              ({
                key: key.replace( /([A-Z])/g, "-$1").toLowerCase(),
                value
              })
          )
          .reduce(
              (css, {key, value}) => 
                  `${css} ${key}: ${value}; `.trim(), 
              '')
Tabbyofjudah
la source
1

Vous trouverez ci-dessous un lien qui démontre la chaîne de cas de camel en chaîne de phrase en utilisant regex.

Contribution

myCamelCaseSTRINGToSPLITDemo

Production

my Camel Case STRING To SPLIT Demo


Ceci est regex pour la conversion de la casse de chameau en texte de phrase

(?=[A-Z][a-z])|([A-Z]+)([A-Z][a-rt-z][a-z]\*)

avec $1 $2comme subsitution.

Cliquez pour voir la conversion sur regex

Rahul
la source
Fournissez le contenu pertinent de votre lien dans le corps de votre réponse.
Grant Miller
1

Entrée javaScript

Script Java de sortie

   var text = 'javaScript';
    text.replace(/([a-z])([A-Z][a-z])/g, "$1 $2").charAt(0).toUpperCase()+text.slice(1).replace(/([a-z])([A-Z][a-z])/g, "$1 $2");
Manas
la source
1

Encore une solution basée sur RegEx.

respace(str) {
  const regex = /([A-Z])(?=[A-Z][a-z])|([a-z])(?=[A-Z])/g;
  return str.replace(regex, '$& ');
}

Explication

Le RegEx ci-dessus se compose de deux parties similaires séparées par l' opérateur OR . La première moitié:

  1. ([A-Z]) - correspond aux lettres majuscules ...
  2. (?=[A-Z][a-z]) - suivi d'une séquence de lettres majuscules et minuscules.

Lorsqu'il est appliqué à la séquence FOo , cela correspond effectivement à sa lettre F.

Ou le deuxième scénario:

  1. ([a-z]) - correspond aux lettres minuscules ...
  2. (?=[A-Z]) - suivi d'une lettre majuscule.

Lorsqu'il est appliqué à la séquence barFoo , cela correspond effectivement à sa lettre r .

Lorsque tous les candidats de remplacement ont été trouvés, la dernière chose à faire est de les remplacer par la même lettre mais par un espace supplémentaire. Pour cela, nous pouvons utiliser '$& 'comme remplacement, et cela se résoudra en une sous-chaîne correspondante suivie d'un caractère espace.

Exemple

const regex = /([A-Z])(?=[A-Z][a-z])|([a-z])(?=[A-Z])/g
const testWords = ['ACoolExample', 'fooBar', 'INAndOUT', 'QWERTY', 'fooBBar']

testWords.map(w => w.replace(regex, '$& '))
->(5) ["A Cool Example", "foo Bar", "IN And OUT", "QWERTY", "foo B Bar"]
Itachi
la source
-1

Ajout d'une autre solution ES6 que j'aimais mieux après ne pas être satisfait de quelques réflexions ci-dessus.

https://codepen.io/902Labs/pen/mxdxRv?editors=0010#0

const camelize = (str) => str
    .split(' ')
    .map(([first, ...theRest]) => (
        `${first.toUpperCase()}${theRest.join('').toLowerCase()}`)
    )
    .join(' ');
user169251
la source