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

174

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

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

Волшебник сделал это
источник
Дубликат: stackoverflow.com/questions/1026069/…
Стивен
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цикл.

PleaseStand
источник
Первая функция разбивает его, но не переводит 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"

Вы также можете настроить, как указано выше, чтобы использовать первый символ.

thegreenpizza
источник
10
function spacecamel(s){
    return s.replace(/([a-z])([A-Z])/g, '$1 $2');
}

spacecamel ( '') somethingLikeThis

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

Kennebec
источник
1
Хороший! это именно то, что мне было нужно, я хотел разделить, например: DiscoveryChannel и HBO другие ответы дали мне Discovery Channel и HBO, но ваш ответ помог мне, так как HBO остался нетронутым, спасибо!
AJS
4

Решение, которое также обрабатывает числа:

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

Протестировано здесь [JSFiddle, нет библиотеки. Не пробовал IE]; должно быть довольно стабильным.

SamGoody
источник
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"
pykiss
источник
Я применил эту функцию в цикле на 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;
M3ghana
источник
-5

Не регулярное выражение, но полезно знать простые и старые методы, подобные этой:

var origString = "thisString";
var newString = origString.charAt(0).toUpperCase() + origString.substring(1);
грабить
источник
5
нет, вопрос «thisString» в «This String» (с пробелом), а не «ThisString»
Пит
@rob Как вы помещаете пробел между «this» и «String»?
ThunderBird