Як перетворити “camelCase” на “Camel Case”?


174

Я намагався отримати команду регулярок JavaScript , щоб включити що - щось на зразок "thisString"в "This String"але ближче я отримав заміну листи, в результаті чого - щось на зразок "Thi String"або "This tring". Будь-які ідеї?

Щоб уточнити, що я можу впоратися з простотою написання великої літери, я просто не такий сильний з RegEx, і розбитися "somethingLikeThis"на те "something Like This", де я маю проблеми.



6
Як це дублікат цього. Все, що робиться, - це використання великих літер у рядку, нічого близького до того, що я хочу зробити.
Чарівник зробив це

Хм, це не справді питання, але результат може бути однаковим. Або це не те, що ти хотів зробити? Більше розвивати?
суперфро

Для практики регулярного вираження я пропоную RegExr або Expresso протестувати і просто подивитися на всі питання регулярного вираження на SO та спробувати відповісти на них. Regexs - це не найпростіша річ у світі, але просто пам’ятайте, що якщо ваш регулярний вираз збиває з пантелику ВАС, то розділіть його та працюйте на частини.
josh.trow

Відповіді:


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

дисплеї

This String Is Good


1
Добрий чоловік, розколовши його. Тільки пам'ятайте Bobince до ради: stackoverflow.com/questions/1732348 / ...
josh.trow

Ви впевнені, що це сумісно з IE? Щойно спробував у IETester7 і отримав помилку.
strongriley

3
Також додаючи: якщо у вас є абревіатура з усіма кришками, яку ви хочете зберегти разом, ви можете змінити перший регекс на "/ ([AZ] [az]) /"
jackfrster

2
"This" -> "This" (небажаний пробіл з префіксами). Можливо, змініть його на: str.slice (0, 1) .toUpperCase () + str.slice (1) .replace (/ ([AZ]) / g, '$ 1')
Марк Вайнгріб

1
@ColdCerberus Ви можете використовувати: str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() );Він перетвориться userIDна User ID, і він навіть перетвориться userIDFieldнаUser ID Field
Євген Мала

87

Я мав інтерес до цього, особливо в обробці послідовностей великих літер, таких як xmlHTTPRequest. Перелічені функції створюють "Xml запит HTTP" або "Xml HTTPRequest", мій виробляє "Xml запит HTTP".

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

Існує також версія String.prototype в суті .


Те саме можна досягти за допомогою двох дзвінків на заміну:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Євген Мала

22

Це можна стисло зробити з regex lookahead ( live demo ):

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

(Я вважав, що g(глобальний) прапор необхідний, але як не дивно, це не в цьому конкретному випадку.)

Використання lookahead з splitгарантує, що відповідні великі літери не будуть витрачені, а також уникнути роботи з провідним простором, якщо UpperCamelCase - це щось, з чим вам потрібно мати справу. Для написання великої літери кожної літери можна скористатися:

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

Метод mapмасиву - це функція ES5, але ви все ще можете використовувати його в старих браузерах з деяким кодом від MDC . Крім того, ви можете перебирати елементи масиву, використовуючи forцикл.


Перша функція розбиває її, але не PascalCase Перше слово. Друга функція не спрацьовує на жодному випадку з верблюдом. (наприклад: 'id')
дементік

16

Я думаю, що це повинно вміти обробляти послідовні великі символи, а також прості camelCase.

Наприклад: someVariable => someVariable, але ABCCode! = ABC Code.

Наведений нижче регекс працює на вашому прикладі, але також є загальним прикладом представлення абревіатур у 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"

Ви також можете налаштувати, як зазначено вище, щоб використовувати великі літери першого символу.


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

космічна камера ("щось так, як це")

// повернене значення: щось подібне


1
Хороший! це саме те, що мені потрібно, я хотів розділити, наприклад: DiscoveryChannel та HBO інші відповіді дали мені Discovery Channel та HBO, але ваша відповідь зробила трюк для мене, оскільки HBO залишився цілим спасибі!
AJS



0

Якщо ви не переймаєтесь старшими браузерами (або не заперечуєте за допомогою функції зменшення резервного копіювання для них), це може розділити навіть рядки типу "xmlHTTPRequest" (але, звичайно, "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

Моя версія

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"

Я застосував цю функцію в циклі на 3000 рядків і отримав ці пробіли перед кожним рядком, який починається з великої літери
Домінік Доманський,

0

Спробуйте це рішення тут -

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

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

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

5
ні, питання "thisString" до "This String" (з пробілом) не "ThisString"
Піт Кіркхем

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