admin管理员组文章数量:1323730
function hyphenate(str) {
var replace = "-";
str = str.toLowerCase().replace(/[\s_\b]/g, replace);
console.log(str);
return str;
}
hyphenate("This Is Hyphenate"); // this-is-hyphenate
hyphenate("camelCaseString"); // camel-case-string
I am trying to get my code to produce the results of the second function call, but have not identified a pattern that can do this. Any assistance would be greatly appreciated.
function hyphenate(str) {
var replace = "-";
str = str.toLowerCase().replace(/[\s_\b]/g, replace);
console.log(str);
return str;
}
hyphenate("This Is Hyphenate"); // this-is-hyphenate
hyphenate("camelCaseString"); // camel-case-string
I am trying to get my code to produce the results of the second function call, but have not identified a pattern that can do this. Any assistance would be greatly appreciated.
Share Improve this question edited Apr 16, 2020 at 8:55 Wiktor Stribiżew 628k41 gold badges498 silver badges611 bronze badges asked Jan 30, 2016 at 0:00 brndngbrndng 1031 silver badge7 bronze badges4 Answers
Reset to default 6Note that \b
in your [\s_\b]
means a backspace character. Not sure you really need this.
Updated answer using the lookbehind feature introduced in ECMAScript 2018:
const re = /[\W_]+|(?<=[a-z0-9])(?=[A-Z])/g;
const strs = ['camelCaseString','This Is Hyphenate','This_Should_Hyphenate', '09Report'];
strs.forEach(str =>
console.log( str.replace(re, "-").toLowerCase() )
);
The [\W_]+|(?<=[a-z0-9])(?=[A-Z])
regex will match
[\W_]+
- any 1+ non-word and_
chars|
- or(?<=[a-z0-9])(?=[A-Z])
- a location between a lowercase ASCII letter/digit and an uppercase ASCII letter.
Old answer
I'd use a bit different logic: add a hyphen before each capital letter inside a word, and then replace and turn lowercase:
var re = /[\s_]+|([a-z0-9])(?=[A-Z])/g;
var str = 'camelCaseString<br/>This Is Hyphenate<br/>This_Should_Hyphenate';
var result = str.replace(re, "$1-").toLowerCase();
document.body.innerHTML += result;
Explanation:
[\s_]+
- one or more whitespaces or underscores|
- or...([a-z0-9])
- (Group 1) a lowercase letter or digit (since\B
would not let us match an uppercase letter after_
, addA-Z
if you want to add-
before each uppercase letter)(?=[A-Z])
- a test for an uppercase ASCII letter (that is not consumed since it(?=[A-Z])
is a lookahead, a zero width assertion).
Try a lookahead before lowercasing:
function hyphenate(str) {
return str.split(/[\s_\b]|(?=[A-Z])/).join('-').toLowerCase();
}
You can use capture groups to get the lowercase followed by the upper case letter, and then convert the whole string to lowercase:
str.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase();
This maybe overkill to your requirements, but hopefully this answer will help anyone who is trying to convert (almost) any string into kebab case:
const convertStringToKebebCase = str => str && str
.match(/[0-9]{1,}(?=\b)|[A-Z]{2,}(?=[A-Z][a-z]+|[0-9]|\b|_)|[A-Z]?[a-z]+|[A-Z]|[0-9]+/g)
.map(x => x.toLowerCase())
.join('-')
Here are the tests for the above function so you can work out how it behaves (I renamed the function to toKebeb
just to make it easier to read here):
// Lowercase
expect(toKebeb('path')).toEqual('path')
expect(toKebeb('PATH')).toEqual('path')
// Spaces
expect(toKebeb('path route')).toEqual('path-route')
expect(toKebeb('path route 0')).toEqual('path-route-0')
expect(toKebeb('123 path 4 route 567')).toEqual('123-path-4-route-567')
// Kebab
expect(toKebeb('path-route')).toEqual('path-route')
expect(toKebeb('PATH-ROUTE')).toEqual('path-route')
expect(toKebeb('path-route0')).toEqual('path-route-0')
expect(toKebeb('path-route-0')).toEqual('path-route-0')
expect(toKebeb('123-path-4-route-567')).toEqual('123-path-4-route-567')
expect(toKebeb('123-path-4-route-567')).toEqual('123-path-4-route-567')
// Snake
expect(toKebeb('path_route')).toEqual('path-route')
expect(toKebeb('PATH_ROUTE')).toEqual('path-route')
expect(toKebeb('path_route0')).toEqual('path-route-0')
expect(toKebeb('path_route_0')).toEqual('path-route-0')
expect(toKebeb('123_path_4_route_567')).toEqual('123-path-4-route-567')
expect(toKebeb('123_path_4_route_567')).toEqual('123-path-4-route-567')
// Camel
expect(toKebeb('pathRoute')).toEqual('path-route')
expect(toKebeb('pathROUTE')).toEqual('path-route')
expect(toKebeb('pathRoute0')).toEqual('path-route-0')
expect(toKebeb('pathROUTE0')).toEqual('path-route-0')
expect(toKebeb('123path4Route567')).toEqual('123-path-4-route-567')
expect(toKebeb('123path4ROUTE567')).toEqual('123-path-4-route-567')
expect(toKebeb('pathRouteA')).toEqual('path-route-a')
expect(toKebeb('pathRouteABC')).toEqual('path-route-abc')
expect(toKebeb('pathIsARoute')).toEqual('path-is-a-route')
// Other
expect(toKebeb('path-route0')).toEqual('path-route-0')
expect(toKebeb('path-route123')).toEqual('path-route-123')
expect(toKebeb('path1route')).toEqual('path-1-route')
expect(toKebeb('path123route')).toEqual('path-123-route')
expect(toKebeb('123pathRoute')).toEqual('123-path-route')
expect(toKebeb('123PATHRoute')).toEqual('123-path-route')
expect(toKebeb('123pathROUTE')).toEqual('123-path-route')
I mentioned that this function converts almost any string, and that is because of the way numbers are handled may differ for each use case. For example, it would be perfectly reasonable to expect 3dPrinter
to return 3d-printer
. The regex can be tweaked to support this, but it raises other issues such as how to handle 3dPrinter12
, my3dPrinter
or se7en
(i.e. which number-string order binations are respected). Supporting such rules would massively increase the number of tests required and there will always be exceptions.
To support the 3dPrinter
example, you could add [0-9]{1,}[a-z]{1,}(?=[A-Z]+)|
to the start of the regex (after the "/"), but it would break some of the earlier rules.
To learn about how this regex works, checkout the pattern on regexr.
本文标签: javascriptRegular rxpression to convert a camel case string into kebab caseStack Overflow
版权声明:本文标题:javascript - Regular rxpression to convert a camel case string into kebab case - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742121958a2421752.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论