const symbols = '\\u0020-\\u0026\\u0028-\\u002F\\u003A-\\u0040\\u005B-\\u0060\\u007B-\\u007E\\u00A0-\\u00BF\\u00D7\\u00F7'; const lowers = 'a-z\\u00DF-\\u00F6\\u00F8-\\u00FF'; const uppers = 'A-Z\\u00C0-\\u00D6\\u00D8-\\u00DE'; const reUpper = new RegExp('^[^' + lowers + ']+$'); const reRoom = new RegExp('[' + symbols + ']'); const reRelax = new RegExp('([^' + uppers + '])([' + uppers + ']*)([' + uppers + '])(?=[^' + uppers + ']|$)', 'g'); const reFill = new RegExp('[' + symbols + ']+(.|$)', 'g'); function relax(_match: string, before: string, acronym: string, caps: string): string { return before + ' ' + (acronym ? acronym + ' ' : '') + caps; } export function snakeCase(value: string): string { let s = value == null ? '' : String(value); if (reUpper.test(s)) { s = s.toLowerCase(); } if (!reRoom.test(s)) { s = s.replace(reRelax, relax); } s = s.toLowerCase(); s = s.replace(reFill, (_match, next) => (next ? '_' + next : '')); return s.replace(/'/g, ''); }