camelCase 到 kebab-case

问题描述 投票:0回答:9

我有一个 kebabize 函数,可以将camelCase转换为kebab-case。我正在分享我的代码。能不能再优化一点?我知道这个问题可以使用正则表达式来解决。但是,我想不使用正则表达式来做到这一点。

const kebabize = str => {

    let subs = []
    let char = ''
    let j = 0

    for( let i = 0; i < str.length; i++ ) {

        char = str[i]

        if(str[i] === char.toUpperCase()) {
            subs.push(str.slice(j, i))
            j = i
        }

        if(i == str.length - 1) {
            subs.push(str.slice(j, str.length))
        }
    }

    return subs.map(el => (el.charAt(0).toLowerCase() + el.substr(1, el.length))).join('-')
}

kebabize('myNameIsStack')
javascript ecmascript-6
9个回答
53
投票

我有一个类似于 Marc 的单行代码,但具有更简单的正则表达式,根据我的基准测试(Chrome 89),速度快了约 20%。

const kebabize = (str) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? "-" : "") + $.toLowerCase())

const words = ['StackOverflow', 'camelCase', 'alllowercase', 'ALLCAPITALLETTERS', 'CustomXMLParser', 'APIFinder', 'JSONResponseData', 'Person20Address', 'UserAPI20Endpoint'];

console.log(words.map(kebabize));

[A-Z]+(?![a-z])
匹配任何连续的大写字母,不包括任何大写字母后跟小写字母(表示下一个单词)。添加
|[A-Z]
然后包含所有单个大写字母。它必须位于连续大写表达式之后,否则表达式将单独匹配所有大写字母,并且永远不会匹配连续的大写字母。

String.prototype.replace
可以带替换功能。在这里,当匹配偏移量为真(不为零 - 不是字符串的第一个字符)时,在添加连字符前缀后,它返回每个单词的小写匹配大写字母。

我怀疑 Marc 的解决方案性能不如我的,因为通过使用替换插入连字符并随后将整个字符串小写,它必须多次迭代字符串,并且其表达式还具有更复杂的前向/后向结构。

基准


33
投票

const kebabize = str => {
   return str.split('').map((letter, idx) => {
     return letter.toUpperCase() === letter
      ? `${idx !== 0 ? '-' : ''}${letter.toLowerCase()}`
      : letter;
   }).join('');
}

console.log(kebabize('myNameIsStack'));
console.log(kebabize('MyNameIsStack'));

您可以检查每个字母是否大写并替换它。


17
投票

RegEx 更快!

与您可能想象的不同,RegEx 的执行方式实际上要快得多!请参阅基准

下面的函数支持将

camelCase
PascalCase
转换为
kebab-case
:

function toKebabCase(str) {
    return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
}

11
投票

这是我的解决方案:

适用于驼峰命名法和帕斯卡命名法:

let words = ['StackOverflow', 'camelCase', 'alllowercase', 'ALLCAPITALLETTERS', 'CustomXMLParser', 'APIFinder', 'JSONResponseData', 'Person20Address', 'UserAPI20Endpoint'];

let result = words.map(w => w.replace(/((?<=[a-z\d])[A-Z]|(?<=[A-Z\d])[A-Z](?=[a-z]))/g, '-$1').toLowerCase());

console.log(result);

/*

Returns:
[
  "stack-overflow",
  "camel-case",
  "alllowercase",
  "allcapitalletters",
  "custom-xml-parser",
  "api-finder",
  "json-response-data",
  "person20-address",
  "user-api20-endpoint"
]

*/

说明:

  1. 匹配以下任意正则表达式:
  • 找到任何大写字母,其前面紧跟着一个小写字母或数字,或者
  • 找到前面紧跟着一个大写字母的任何大写字母或后面紧跟着一个小写字母的数字
  1. 用破折号('-')替换捕获的位置,后跟捕获的大写字母
  2. 最后,将整个字符串转换为小写。

3
投票

我会用这样的东西。

function kebabize(string) {
  // uppercase after a non-uppercase or uppercase before non-uppercase
  const upper = /(?<!\p{Uppercase_Letter})\p{Uppercase_Letter}|\p{Uppercase_Letter}(?!\p{Uppercase_Letter})/gu;
  return string.replace(upper, "-$&").replace(/^-/, "").toLowerCase();
}


const strings = ["myNameIsStack", "HTTPRequestData", "DataX", "Foo6HelloWorld9Bar", "Áb"];
const result  = strings.map(kebabize);

console.log(result);

此代码片段将非大写字符之前或之后的所有大写字符替换为

-
后跟大写字符。然后它会删除字符串开头的
-
(如果有的话)并将整个字符串小写。


0
投票

针对旧版浏览器的简单解决方案:

var str = 'someExampleString'
var i

function camelToKebab() {
  var __str = arguments[0]
  var __result = ''

  for (i = 0; i < __str.length; i++) {
    var x = __str[i]

    if(x === x.toUpperCase()) {
      __result += '-' + x.toLowerCase()
    } else {
      __result += x
    }
  }

  return __result
}

console.log(str, '->', camelToKebab(str))


0
投票

这是我想出的解决方案:

let resultDiv = document.querySelector(".result");

let camelCase = "thisIsCamelCase";
let kebabCase;
kebabCase = camelCase.split('').map(el=> {
  const charCode = el.charCodeAt(0);
  if(charCode>=65 && charCode<=90){
    return "-" + el.toLowerCase() 
  }else{
    return el;
  }
})

return(kebabCase.join(''))

0
投票

您当前的实现做得很好,但是有几种方法可以使其更加高效或更简洁。这是函数的稍微优化版本,保留了核心逻辑,但稍微简化了一点:

const kebabize = str => {
    let result = ''; // Use a single string to build the result

    for (let i = 0; i < str.length; i++) {
        let char = str[i];
        
        // Check if the character is uppercase
        if (char === char.toUpperCase() && i !== 0) { // Add a dash before uppercase letters, except the first character
            result += '-';
        }
        
        result += char.toLowerCase(); // Add the lowercase version of the current character to the result
    }

    return result;
};

console.log(kebabize('myNameIsStack')); // Outputs: my-name-is-stack


0
投票

如果有人需要将所有大写字母分开,例如

const example1 = 'someExampleString'
const example2 = 'multiWordTogetherXYZ'


function camelToKebabCase(strToChange) {
  return strToChange.replace(/(?:^|\.?)([A-Z])/g, (x, y) => '-' + y.toLowerCase()).replace(/^-/, '');
}

console.log(example1, '->', camelToKebabCase(example1)) // some-example-string
console.log(example2, '->', camelToKebabCase(example2)) // multi-word-together-x-y-z

© www.soinside.com 2019 - 2024. All rights reserved.