如何将驼峰命名法转换为蛇形命名法?

100

我想使用TypeScript将一个驼峰式字符串转换为蛇形式。

请记住,“蛇形式”是指每个空格都被下划线(_)字符替换,并且每个单词的第一个字母小写的格式样式。

例如:fieldName 转换为 field_name 应该是有效的转换,但 FieldName 转换为 Field_Name 是无效的。


2
你尝试过什么?我会使用正则表达式以大写字母为分隔符开始拆分。 - Jeff
4
Java和JavaScript之间的关系就像疼痛和绘画,或者火腿和仓鼠之间的关系一样,它们是完全不同的。强烈建议有志于编程的人先学习他们试图编写代码所使用的语言名称。当您发布问题时,请适当地打标签。 - CertainPerformance
7个回答

240
const camelToSnakeCase = str => str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);

6
当我使用大驼峰式命名法转换为蛇形命名法时,它无法正常工作。ItemName=_item_name - Badrul
32
@Badrul,然而这更符合 PascalCase 命名规范。 - Luke
12
项目名称 => item_name: const camel_to_snake = str => str[0].toLowerCase() + str.slice(1, str.length).replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`); - e382df99a7950919789725ceeec126
8
这个版本也适用于大驼峰命名法。str.replace(/[A-Z]/g, (letter, index) => { return index == 0 ? letter.toLowerCase() : '_'+ letter.toLowerCase();}); - Hrishi
7
我的变体可以很好地处理首字母大写的情况: text.split(/(?=[A-Z])/).join('_').toLowerCase() - Evseev Vadim
显示剩余5条评论

27

你可以像这样做:

function camelToUnderscore(key) {
   var result = key.replace( /([A-Z])/g, " $1" );
   return result.split(' ').join('_').toLowerCase();
}

console.log(camelToUnderscore('itemName'));

稍微修改过的代码:var result = (value .replace(/[^A-Za-z0-9_]/g, '') .replace(/([A-Z]+)/g, " $1") .replace(/\s+/g, ' ') .trim() .toLowerCase() .replace(/\s/g, '')); if (/^\d/.test(result)) { result = "x" + result; } - abasar
4
@abasar,您稍微修改版本的优点是什么? - run_the_race

5

试试这个:

function toSnakeCase(inputString) {
    return inputString.split('').map((character) => {
        if (character == character.toUpperCase()) {
            return '_' + character.toLowerCase();
        } else {
            return character;
        }
    })
    .join('');
}
// x = item_name

1
你需要重新加入数组。 - user578895
@MarkKahn 忘记了 - 谢谢! - Amats
1
谢谢!这非常有帮助。对于我来说,我还添加了一个检查来确保新字符串不以下划线开头,通过将您的 '_' 替换为 (index != 0 ? '_': '') 并将索引作为参数添加到 map 函数中 ...map((character, index) => {... - MoralCode
1
我还使用了 https://dev59.com/o2855IYBdhLWcg3wSSKl#55521416/ 上的答案来为这个函数添加一个检查字母字符的功能,以便数字和符号(在将它们大写后是相同的字符)不会导致该函数在传递snake_case字符串时仅不断加倍下划线的数量。然而,这也有一个缺陷,即将输入限制为仅硬编码字符集。 - MoralCode

4
我已经使用下面的函数进行了测试,并处理了大部分情况。
    function convertToSnakeCase(str) {
      str = str[0].toLowerCase() + str.slice(1, str.length).replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
      str  = str.replaceAll(" _","_")

      return str.replaceAll(" ","_").replace(/(^_*|_*$)/g, '');;
   }

已处理测试用例

convertToSnakeCase("Payas AsdDs asD")
'payas_asd_ds_as_d'

convertToSnakeCase("Payas AsdDs")
'payas_asd_ds'

convertToSnakeCase("Pay  AsdDs")
'pay__asd_ds'

convertToSnakeCase('test_') 
'test';

我认为这个解决方案,如果一个字符串以空格结尾(例如 test ),它会附加 _(例如 test_),因此我建议在最后一个替换中删除前导和尾随下划线:const convertToSnakeCase = s => s.replace(/[A-Z]/g, l => _${l.toLowerCase()}).replace(/ +_*/g, '_').replace(/(^_*|_*$)/g, '')。另外,最终的测试用例结果(pay__asd_ds)是无效的 snake_case 字符串,因为它包含两个连续的 _ 字符。 - tukusejssirs
1
我的测试用例:convertToSnakeCase('Payas AsdDs asD') === 'payas_asd_ds_as_d'; convertToSnakeCase('Payas AsdDs') === 'payas_asd_ds'; convertToSnakeCase('Pay AsdDs') === 'pay_asd_ds'; convertToSnakeCase('thisIsAnExample') === 'this_is_an_example'; convertToSnakeCase('test_') === 'test';. - tukusejssirs
1
SO的格式化删除了我之前评论中的反引号,因此以下是正确的代码:const convertToSnakeCase = s => s.replace(/[A-Z]/g, l => `_${l.toLowerCase()}`).replace(/ +_*/g, '_').replace(/(^_*|_*$)/g, '') - tukusejssirs

1
如果你愿意使用外部库,最简单的方法可能是使用lodash的_.snakeCase(string)函数。

1
在研究正则表达式领域时,我发现了一个很酷的功能,叫做正向前瞻(它匹配主表达式后面的一个组,但不包括在结果中)

以前的方法是在每个大写字母前加上_,包括字符串中的第一个位置。

所以让我们使用正向前瞻来修复这个问题吧;)

function convertCamelToSnake(str){
 return str.replace(/([a-zA-Z])(?=[A-Z])/g,'$1_').toLowerCase()
}

console.log(convertCamelToSnake('camelCaseUrl')) // camel_case_url
console.log(convertCamelToSnake('HereIsABigCamelCaseStr')) // here_is_a_big_camel_case_str


1

如果首字母是大写,接受的答案将以_开头。这解决了问题。

 export function camelToSnake(string = '') {
  return (string || '')
    .replace(/([A-Z])/g, (match, group) => `_${group.toLowerCase()}`)
    .replace(/^_/, '')
}

我认为你不需要两次默认为 '' - Cadoiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接