Как конвертировать «CamelCase» в «Camel Case»?


174

Я пытался заставить команду JavaScript regex превратить что-то вроде "thisString"в, "This String"но самое близкое, что я получил, это замена буквы, в результате чего-то вроде "Thi String"или "This tring". Любые идеи?

Чтобы прояснить, я могу справиться с простотой использования заглавной буквы, я не так силен с RegEx, и я разбираюсь "somethingLikeThis"в "something Like This"том, где у меня возникают проблемы.



6
Как это дубликат этого. Все, что делает, это пишет с заглавной буквы первый символ в строке, ничего похожего на то, что я хочу сделать.
Волшебник сделал это

Хм, это не вопрос вопроса, но результат может быть таким же. Или это не то, что вы хотели сделать? Разработать больше?
Superfro

Для практики регулярных выражений я предлагаю RegExr или Expresso пройти тестирование и просто посмотреть на все вопросы регулярных выражений в SO и попытаться ответить на них. Регулярные выражения - не самая простая вещь в мире, но просто помните, что если ваше регулярное выражение вводит вас в заблуждение, то разбейте его на части и разбейте на части.
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
Хороший человек, разделив это. Просто помните совет Бобинса: 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-запрос XML» или «HTTPRequest Xml», моя - «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(); })
}

В сущности есть также версия String.prototype .


То же самое может быть достигнуто с 2 замену вызовов:str.replace(/((?<!^)[A-Z](?![A-Z]))(?=\S)/g, ' $1').replace(/^./, s => s.toUpperCase() )
Евгений Мала

22

Это может быть кратко сделано с помощью регулярных выражений lookahead ( живая демонстрация ):

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

(Я думал, что g(глобальный) флаг был необходим, но как ни странно, это не в данном конкретном случае.)

Использование функции lookahead with 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')
Dementic

16

Я думаю, что это должно быть в состоянии обрабатывать последовательные символы в верхнем регистре, а также простой CamelCase.

Например: someVariable => someVariable, но ABCCode! = ABC-код.

Приведенное ниже регулярное выражение работает на вашем примере, но также является распространенным примером представления сокращений в 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');
}

spacecamel ( '') somethingLikeThis

// возвращаемое значение: что-то вроде этого


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 Как вы помещаете пробел между «this» и «String»?
ThunderBird
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.