繁体   English   中英

将驼峰字符串转换为烤肉串的常规 rxpression

[英]Regular rxpression to convert a camel case string into kebab case

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

我试图让我的代码产生第二个函数调用的结果,但还没有确定可以做到这一点的模式。 任何帮助将不胜感激。

需要注意的是\\b[\\s_\\b]表示退格字符。 不确定你真的需要这个。

使用 ECMAScript 2018 中引入的后视功能更新了答案

 const re = /[\\W_]+|(?<=[a-z0-9])(?=[AZ])/g; const strs = ['camelCaseString','This Is Hyphenate','This_Should_Hyphenate', '09Report']; strs.forEach(str => console.log( str.replace(re, "-").toLowerCase() ) );

[\\W_]+|(?<=[a-z0-9])(?=[AZ])正则表达式将匹配

  • [\\W_]+ - 任何 1+ 个非单词和_字符
  • | - 或者
  • (?<=[a-z0-9])(?=[AZ]) - 小写 ASCII 字母/数字和大写 ASCII 字母之间的位置。

旧答案

我会使用一些不同的逻辑:在单词内的每个大写字母前添加一个连字符,然后替换并变成小写:

 var re = /[\\s_]+|([a-z0-9])(?=[AZ])/g; var str = 'camelCaseString<br/>This Is Hyphenate<br/>This_Should_Hyphenate'; var result = str.replace(re, "$1-").toLowerCase(); document.body.innerHTML += result;

解释:

  • [\\s_]+ - 一个或多个空格或下划线
  • | - 或者...
  • ([a-z0-9]) - (第 1 组)小写字母或数字(因为\\B不允许我们在_之后匹配大写字母,如果您想在每个大写字母之前添加- ,请添加AZ
  • (?=[AZ]) - 对大写 ASCII 字母的测试(由于它(?=[AZ])是前瞻,零宽度断言,因此不会被消耗)。

在小写之前尝试先行:

function hyphenate(str) {
  return str.split(/[\s_\b]|(?=[A-Z])/).join('-').toLowerCase();
}

您可以使用捕获组来获取小写字母后跟大写字母,然后将整个字符串转换为小写字母:

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

这可能对您的要求有点过分,但希望这个答案能帮助任何试图将(几乎)任何字符串转换为烤肉串的人:

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('-')

以下是对上述函数的测试,因此您可以了解它的行为(我将函数重命名为toKebeb只是为了更容易在此处阅读):

// 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')

我提到这个函数几乎可以转换任何字符串,这是因为每个用例的数字处理方式可能不同。 例如,期望3dPrinter返回3d-printer是完全合理的。 可以调整正则表达式以支持这一点,但它会引发其他问题,例如如何处理3dPrinter12my3dPrinterse7en (即,遵守哪些数字-字符串顺序组合)。 支持此类规则将大量增加所需的测试数量,并且总会有例外。

要支持3dPrinter示例,您可以添加[0-9]{1,}[az]{1,}(?=[AZ]+)| 到正则表达式的开头(在“/”之后),但它会破坏一些早期的规则。

要了解此正则表达式的工作原理,请查看regexr上的模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM