Перетворити camelCaseText у текст справи про вирок


144

Як я можу перетворити рядок, наприклад "helloThere" або "HelloThere", в "Hello There" в JavaScript?


9
хм .. який очікуваний вихід для iLiveInTheUSA?
Вім

8
Я живу в U ... о, лайно! - Але в моєму випадку у мене обмежений набір рядків і немає таких рядків, які могли б зламати простий перетворювач. Хороший улов хоч!
HyderA

Так само uSBPort повинен призвести до "USB-порту"
signonsridhar

2
@wim: iLiveInTheUSA має бути iLiveInTheUsa в правильному позначенні випадку верблюда, але це може спричинити різні проблеми.
Конрад Геффнер

Відповіді:


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

з великої літери - як приклад.

Зверніть увагу на пробіл у " $1".

EDIT: додано приклад з великої літери першої літери. Звичайно, якщо перший лист вже є великим - у вас буде запасний простір.


1
Я копаю використання пробілів у text.replace, я
замінював

8
uSBPorts => USB-порти, не те, що я очікую, я хочу USB-порти
signonsridhar

а як писати Non-GoogleChrome?
час

107

Альтернативно, використовуючи lodash :

lodash.startCase(str);

Приклад:

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

Lodash - це прекрасна бібліотека, яка дає ярлики для багатьох повсякденних js завдань. Є багато інших подібних функцій маніпуляції з рядками, таких як camelCase, kebabCaseтощо.


Якщо ви спробуєте, hello worldтоді результат повинен бути Hello There, в цьому випадку loadash не буде корисним.
Абхішек Кумар

@AbhishekKumar startCase of lodash фактично перетвориться hello worldна Hello World lodash.com/docs/4.17.15#upperFirst
користувача1696017

Ви правий брате. Помилково я написав hello thereв hello world.
Абхішек Кумар

2
Кожен раз, коли я думаю, що "немає способу лодаш зробити це також", це робить.
efru

Будьте обережні, оскільки v4 ця функція видаляє спеціальні символи типу ä і перетворює їх у ASCII (a в цьому випадку)
collerek

52

У мене була подібна проблема, і я вирішував її так:

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

Для більш надійного рішення:

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

http://jsfiddle.net/PeYYQ/

Вхід:

 helloThere 
 HelloThere 
 ILoveTheUSA
 iLoveTheUSA

Вихід:

 hello There 
 Hello There 
 I Love The USA
 i Love The USA

це ставить додатковий простір для початку
hannad rehman

4
Це не вирок, як просив ОП. Перший лист має бути з великої літери.
H Dog

Крім того, це додає додатковий пробіл між словами
Alacritas

34

Приклад без побічних ефектів.

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();
    });
}

В ES6

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

1
Суцільний, +1 для фрагмента es6.
BradStell

4
FYI, це додає додаткового пробілу на початку речення.
Дейл Зак

20

Найкращий рядок, який я знайшов для тестування функцій верблюда від випадку до назви, - це смішний безглуздий приклад, який перевіряє безліч кращих справ. Наскільки мені відомо, жодна з раніше розміщених функцій не справляється з цим правильно :

ToGetYourGEDInTimeASong AboutThe26ABCsIsOfTheEssenceButAPersonalIDCardForUser456InRoom26AContainABC26TimesIsNotAsEasyAs123ForC3POOrR2D2Or2R2D

Це слід перетворити на:

Вчасно отримати вашу GED пісню про 26 ABC - це суть, але особиста посвідчення особи для користувача 456 У номері 26A, що містить ABC 26 Times, не так просто, як 123 для C3PO або R2D2 або 2R2D

Якщо ви хочете просто просту функцію, яка обробляє такі випадки, як описана вище (і більше випадків, ніж багато попередніх відповідей), ось ця я написала. Цей код не особливо елегантний або швидкий, але він простий, зрозумілий і працює.

Приклад запуску в Інтернеті наведено на jsfiddle , або ви можете переглянути висновок фрагмента нижче на своїй консолі:

// 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)));


11

На підставі одного з прикладів вище я придумав це:

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

Це працює для мене, оскільки він використовує .trim()обробку крайового регістру, коли перша літера пишеться з великої літери, і ви отримуєте додатковий пробіл.

Довідка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim


10

Гаразд, я запізнився на кілька років до гри, але у мене виникло подібне запитання, і я хотів зробити рішення за одну заміну на кожен можливий внесок. Я повинен надати більшу частину заслуги @ZenMaster у цій темі та @Benjamin Udink десять Кейт у цій темі. Ось код:

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

У ньому є три застереження, усі вони використовують lookahead, щоб запобігти появі занадто багато символів:

  1. [A-Z](?=[A-Z][a-z])шукає великої літери, за якою йде велика літера, а потім маленька літера. Це для закінчення абревіатур, як США.
  2. [^A-Z](?=[A-Z])шукає не великої літери, а потім великої літери. На цьому закінчуються слова, такі як myWord та символи, як 99Bottles.
  3. [a-zA-Z](?=[^a-zA-Z])шукає листа, за яким йде не літера. Цим закінчуються слова перед символами типу BFG9000.

Це питання опинилось у верхній частині моїх результатів пошуку, тому, сподіваюся, я можу заощадити інших на деякий час!


9

Ось моя версія його. Він додає пробіл перед кожним англійським письмом UpperCase, що надходить після малого англійського письма, а також, при необхідності, використовує великі літери:

Наприклад:
thisIsCamelCase -> Це Case Camel,
це IsCamelCase -> Це Case
Camel

  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;
  }

6

Ця реалізація враховує послідовні великі літери та цифри.

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

Очікуваний вихід:

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

Я б використав відповідь Кріса Клайна, яка містить рядки типу "IP-адреса" (де ця функція перетворює її на "IP-адресу"
Джон Хамм,

@JohnHamm Вхід "IP-адреса", правда? Це не справа верблюда! Прочитайте про те, що тут знаходиться у справі верблюдів: en.wikipedia.org/wiki/Camel_case Не ставте пробіл між ними та введіть лише "IPAddress". Ця функція чудово працює.
Діпу

3

Ви можете використовувати таку функцію:

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"

Код з купою тестових рядків тут: http://jsfiddle.net/jfriend00/FWLuV/ .

Альтернативна версія, яка зберігає провідні місця тут: http://jsfiddle.net/jfriend00/Uy2ac/ .


Я знаю, що це не було вимогою у питанні, але, наприклад, ваше рішення не працює " helloWorld".
ZenMaster

Так, це нова вимога. Я намагався зробити саме те, що ви спочатку просили. У будь-якому випадку, шлях короткого відрізання легко усунути провідні простори, якщо вони вам все одно не потрібні. Якщо ви хочете, щоб їх залишили на місці, це теж можна зробити.
jfriend00

Ось jsFiddle, який показує метод, який працює з новою вимогою "helloWorld" і зберігає провідний простір (якщо ви цього хочете): jsfiddle.net/jfriend00/Uy2ac .
jfriend00

Приємно. Мені цікаво з приводу його виконання. Функція обробника буде викликатись у кожному матчі, чи не так?
ZenMaster

Якщо ви робите мільйон з них у налаштуваннях, залежних від продуктивності, знадобиться кілька тестів jsperf у купі браузерів, щоб побачити, яке саме швидке рішення буде. Виклик зворотного дзвінка - не велика справа. Регулярні вирази будь-якого типу рідко є найшвидшим рішенням проти коду спеціального призначення, але вони економлять багато коду (а часто і деякі помилки), тому часто є бажаним вибором. Це залежить від ваших вимог.
jfriend00

3

спробуйте цю бібліотеку

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"

2

Жодна з вищезгаданих відповідей для мене не працювала ідеально, тому довелося прийти з власним велосипедом:

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

Тестові приклади:

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

2

Це працює для мене перевірити це

CamelcaseToWord ("MyName"); // повертає Моє ім’я

    function CamelcaseToWord(string){
      return string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, " $1");
    }

1
Ласкаво просимо до SO :) Будь ласка, додайте до коду хоча б один пояснювальний рядок. Також переконайтеся, що це ваша інтелектуальна робота, або наведіть джерело (джерела).
Лоренц Ло Зауер

Вам слід видалити простір у латі "$ 1". string.replace(/([A-Z]+)/g, " $1").replace(/([A-Z][a-z])/g, "$1");
Валерія Шпінер

2

Я думаю, що це можна зробити просто за допомогою reg exp /([a-z]|[A-Z]+)([A-Z])/gта заміни "$1 $2".

ILoveTheUSADope -> Я люблю допінг США


Не точно, для рядка QWERTYвін повертається QWERT Y.
itachi

2

Якщо ви маєте справу з Capital Camel Case, цей фрагмент може допомогти вам, також він містить деякі характеристики, щоб ви могли бути впевнені, що він відповідає вашому випадку.

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

І характеристики:

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

1

Я не пробував відповіді всіх, але декілька рішень, з якими я працював, не відповідали всім моїм вимогам.

Я зміг придумати щось, що зробив ...

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(), 
              '')

1

Нижче посилання, яке демонструє рядок справи верблюда до рядка речення, використовуючи регулярний вираз.

Вхідні дані

myCamelCaseSTRINGToSPLITDemo

Вихідні дані

my Camel Case STRING To SPLIT Demo


Це регулярне вираження для перетворення справи верблюда в текст пропозиції

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

з $1 $2як заміщення.

Клацніть, щоб переглянути конверсію на регулярному вираженні


Надайте відповідний вміст зі свого посилання в тілі вашої відповіді.
Грант Міллер

1

Введення javaScript

Вихід сценарію Java

   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");

1

Ще одне рішення, засноване на RegEx.

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

Пояснення

Вищевказаний RegEx складається з двох подібних частин, розділених оператором АБО . Перша половина:

  1. ([A-Z]) - відповідає великим літерам ...
  2. (?=[A-Z][a-z]) - слідує послідовність великих і малих літер.

Якщо застосовується до послідовності FOo , це ефективно відповідає його букві F.

Або другий сценарій:

  1. ([a-z]) - відповідає малі літери ...
  2. (?=[A-Z]) - далі велика літера.

Якщо застосувати до barFoo послідовності , це ефективно відповідає його r букві .

Коли були знайдені всі кандидати на заміну, останнє, що потрібно зробити, - це замінити їх тим же листом, але з додатковим символом пробілу. Для цього ми можемо використовувати '$& 'в якості заміни, і він вирішиться до збіжної підрядки з подальшим пробілом.

Приклад

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"]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.