如何使用javascript正则表达式将字符串转换为驼峰大小写?

设备类名称或 设备类名或设备类名或设备类名

应该全部变成:equipmentClassName。


当前回答

因为这个问题还需要另一个答案……

我尝试了之前的几种解决方案,它们都有这样或那样的缺陷。有些没有删除标点符号;有些人不处理有数字的案件;有些人不能处理连续多个标点符号。

它们都没有处理a12b这样的字符串。对于这种情况,没有明确定义的约定,但其他一些stackoverflow问题建议用下划线分隔数字。

我怀疑这是性能最好的答案(三个regex通过字符串,而不是一个或两个),但它通过了我能想到的所有测试。不过,老实说,我真的无法想象有一种情况,您执行了如此多的驼峰式转换,以至于性能会变得很重要。

(我添加了一个npm包。它还包括一个可选的布尔参数,以返回Pascal Case而不是Camel Case。)

const underscoreRegex = /(?:[^\w\s]|_)+/g,
    sandwichNumberRegex = /(\d)\s+(?=\d)/g,
    camelCaseRegex = /(?:^\s*\w|\b\w|\W+)/g;

String.prototype.toCamelCase = function() {
    if (/^\s*_[\s_]*$/g.test(this)) {
        return '_';
    }

    return this.replace(underscoreRegex, ' ')
        .replace(sandwichNumberRegex, '$1_')
        .replace(camelCaseRegex, function(match, index) {
            if (/^\W+$/.test(match)) {
                return '';
            }

            return index == 0 ? match.trimLeft().toLowerCase() : match.toUpperCase();
        });
}

测试用例(开玩笑)

test('Basic strings', () => {
    expect(''.toCamelCase()).toBe('');
    expect('A B C'.toCamelCase()).toBe('aBC');
    expect('aB c'.toCamelCase()).toBe('aBC');
    expect('abc      def'.toCamelCase()).toBe('abcDef');
    expect('abc__ _ _def'.toCamelCase()).toBe('abcDef');
    expect('abc__ _ d_ e _ _fg'.toCamelCase()).toBe('abcDEFg');
});

test('Basic strings with punctuation', () => {
    expect(`a'b--d -- f.h`.toCamelCase()).toBe('aBDFH');
    expect(`...a...def`.toCamelCase()).toBe('aDef');
});

test('Strings with numbers', () => {
    expect('12 3 4 5'.toCamelCase()).toBe('12_3_4_5');
    expect('12 3 abc'.toCamelCase()).toBe('12_3Abc');
    expect('ab2c'.toCamelCase()).toBe('ab2c');
    expect('1abc'.toCamelCase()).toBe('1abc');
    expect('1Abc'.toCamelCase()).toBe('1Abc');
    expect('abc 2def'.toCamelCase()).toBe('abc2def');
    expect('abc-2def'.toCamelCase()).toBe('abc2def');
    expect('abc_2def'.toCamelCase()).toBe('abc2def');
    expect('abc1_2def'.toCamelCase()).toBe('abc1_2def');
    expect('abc1 2def'.toCamelCase()).toBe('abc1_2def');
    expect('abc1 2   3def'.toCamelCase()).toBe('abc1_2_3def');
});

test('Oddball cases', () => {
    expect('_'.toCamelCase()).toBe('_');
    expect('__'.toCamelCase()).toBe('_');
    expect('_ _'.toCamelCase()).toBe('_');
    expect('\t_ _\n'.toCamelCase()).toBe('_');
    expect('_a_'.toCamelCase()).toBe('a');
    expect('\''.toCamelCase()).toBe('');
    expect(`\tab\tcd`.toCamelCase()).toBe('abCd');
    expect(`
ab\tcd\r

-_

|'ef`.toCamelCase()).toBe(`abCdEf`);
});

其他回答

基本的方法是用匹配大写或空格的正则表达式分割字符串。然后再把碎片粘回去。技巧将处理各种方式的正则表达式分割是破坏/奇怪的浏览器。有人编写了一个库来解决这些问题;我去找找。

这是链接:http://blog.stevenlevithan.com/archives/cross-browser-split

const toCamelCase = str =>
  str
    .replace(/[^a-zA-Z0-9]+(.)/g, (m, chr) => chr.toUpperCase())
    .replace(/^\w/, c => c.toLowerCase());

我最终想出了一个稍微激进一点的解决方案:

function toCamelCase(str) {
  const [first, ...acc] = str.replace(/[^\w\d]/g, ' ').split(/\s+/);
  return first.toLowerCase() + acc.map(x => x.charAt(0).toUpperCase() 
    + x.slice(1).toLowerCase()).join('');
}

上面的这个方法将删除所有非字母数字字符和单词的小写部分,否则将保持大写,例如。

Size (comparative) => Size比较 GDP(官方汇率)=> Hello => Hello

这是解决方案,包括大写的第一个字母,如果第一个字母最初是大写的。

function toCamelCase(str){
  let newStr = "";
  if(str){
    let wordArr = str.split(/[-_]/g);
    for (let i in wordArr){
      if(i > 0){
        newStr += wordArr[i].charAt(0).toUpperCase() + wordArr[i].slice(1);
      }else{
        newStr += wordArr[i]
      }
    }
  }else{
    return newStr
  }
  return newStr;
}


编辑:现在工作在IE8没有变化。

编辑:我对camelCase到底是什么持少数意见(主角小写vs大写)。一般来说,社区认为开头小写字母是camel大小写,开头大写字母是pascal大小写。我创建了两个只使用正则表达式模式的函数。所以我们使用统一的词汇我已经改变了我的立场以配合大多数人。


我相信在这两种情况下你只需要一个正则表达式:

var camel = " THIS is camel case "
camel = $.trim(camel)
    .replace(/[^A-Za-z]/g,' ') /* clean up non-letter characters */
    .replace(/(.)/g, function(a, l) { return l.toLowerCase(); })
    .replace(/(\s.)/g, function(a, l) { return l.toUpperCase(); })
    .replace(/[^A-Za-z\u00C0-\u00ff]/g,'');
// Returns "thisIsCamelCase"

or

var pascal = " this IS pascal case "
pascal = $.trim(pascal)
  .replace(/[^A-Za-z]/g,' ') /* clean up non-letter characters */
  .replace(/(.)/g, function(a, l) { return l.toLowerCase(); })
  .replace(/(^.|\s.)/g, function(a, l) { return l.toUpperCase(); })
  .replace(/[^A-Za-z\u00C0-\u00ff]/g,'');
// Returns "ThisIsPascalCase"

在函数中:你会注意到,在这些函数中,replace是将任何非a-z与空格与空字符串交换。这是为大写创建单词边界。"hello-MY#world" -> "HelloMyWorld"

// remove \u00C0-\u00ff] if you do not want the extended letters like é
function toCamelCase(str) {
    var retVal = '';

    retVal = $.trim(str)
      .replace(/[^A-Za-z]/g, ' ') /* clean up non-letter characters */
      .replace(/(.)/g, function (a, l) { return l.toLowerCase(); })
      .replace(/(\s.)/g, function (a, l) { return l.toUpperCase(); })
      .replace(/[^A-Za-z\u00C0-\u00ff]/g, '');

    return retVal
}

function toPascalCase(str) {
    var retVal = '';

    retVal = $.trim(str)
      .replace(/[^A-Za-z]/g, ' ') /* clean up non-letter characters */
      .replace(/(.)/g, function (a, l) { return l.toLowerCase(); })
      .replace(/(^.|\s.)/g, function (a, l) { return l.toUpperCase(); })
      .replace(/[^A-Za-z\u00C0-\u00ff]/g, '');

    return retVal
}

注:

为了可读性,我保留了A-Za-z vs为模式(/[^A-Z]/ig)添加大小写不敏感标志(I)。 这可以在IE8中工作(srsly,谁还在使用IE8呢。)使用我在IE11、IE10、IE9、IE8、IE7和IE5中测试过的(F12)开发工具。适用于所有文档模式。 这将正确地对以空格或不以空格开头的字符串的第一个字母进行大小写区分。

享受