DanMad
DanMad

Reputation: 1755

Altered kebab case Regex

I am using the following toKebabCase() function:

function toKebabCase(key) {
  return key.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
    .map((word) => word.toLowerCase())
    .join('-');
}

console.log(toKebabCase('namespaceGray100Light'));

It doesn't behave exactly as I would like, though. Right now, if I pass 'namespaceGray100Light' as an argument, the function returns 'namespace-gray100-light'. How would this regex need to be modified in order to return 'namespace-gray-100-light'.

To clarify, I am looking to introduce a hyphen when a digit follows an alpha character and not just when a digit precedes an alpha character.

TY.

Upvotes: 4

Views: 1460

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627087

You need to remove [0-9]* from the pattern:

function toKebabCase(key) {
  return key.match(/[A-Z]{2,}(?=[A-Z][a-z]+|\b)|[A-Z]?[a-z]+|[A-Z]|[0-9]+/g)
    .map((word) => word.toLowerCase())
    .join('-');
}
console.log(toKebabCase('namespaceGray100Light'));

See the regex demo.

Note that your regex has two occurrences of [0-9]*:

  • (?=[A-Z][a-z]+[0-9]*|\b) - here, [0-9]* is redundant since it can match zero chars, an empty string, and is at the end of the lookahead alternative
  • [A-Z]?[a-z]+[0-9]* - here, the [0-9]* consumes the digits after a letter word, but it is exactly where you need to add a - in between. The digits will get matched with the [0-9]+ last alternative.

Upvotes: 2

Cerbrus
Cerbrus

Reputation: 72927

Just add a replace for that case:

function toKebabCase(key) {
  return key.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
    .map((word) => word.toLowerCase())
    .join('-')
    .replace(/([^\d])(\d)/g, "$1-$2");
}

console.log(toKebabCase('namespaceGray100Light'));

No need to make an already complex regex more complicated.

Upvotes: 0

Related Questions