我有一个 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')
我有一个类似于 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 的解决方案性能不如我的,因为通过使用替换插入连字符并随后将整个字符串小写,它必须多次迭代字符串,并且其表达式还具有更复杂的前向/后向结构。
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'));
您可以检查每个字母是否大写并替换它。
与您可能想象的不同,RegEx 的执行方式实际上要快得多!请参阅基准。
下面的函数支持将
camelCase
和PascalCase
转换为kebab-case
:
function toKebabCase(str) {
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
}
这是我的解决方案:
适用于驼峰命名法和帕斯卡命名法:
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"
]
*/
说明:
我会用这样的东西。
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);
此代码片段将非大写字符之前或之后的所有大写字符替换为
-
后跟大写字符。然后它会删除字符串开头的 -
(如果有的话)并将整个字符串小写。
针对旧版浏览器的简单解决方案:
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))
这是我想出的解决方案:
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(''))
您当前的实现做得很好,但是有几种方法可以使其更加高效或更简洁。这是函数的稍微优化版本,保留了核心逻辑,但稍微简化了一点:
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
如果有人需要将所有大写字母分开,例如
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