CamelCase2snake_case ()


13

Escreva uma função para converter o texto CamelCased em snake_case: FunctionForHTMLManipulationtorna - sefunction_for_html_manipulation

O texto de entrada será um único identificador adequado em vários idiomas. Ele deve começar com uma letra em inglês e, em seguida, ser seguido por qualquer número de letras ou dígitos em inglês. Nenhum outro caractere (espaços, símbolos, etc.) é permitido.

Cada "palavra" no texto do CamelCased começará com uma letra maiúscula, a menos que no início do texto ou imediatamente após um dígito, e seja seguida por zero ou mais letras, todos no mesmo caso. Grupos de dígitos serão considerados como palavras separadas, mas passarão inalterados.

Em outras palavras, uma letra minúscula seguida por uma letra maiúscula indica uma quebra de palavra. Qualquer letra e dígito próximos um do outro indica uma quebra de palavra. Uma letra maiúscula seguida por outra letra maiúscula e uma letra minúscula indica uma quebra de palavra.

...lU...=> ...l_u...
...l9...=> ...l_9...
...U9...=> ...u_9...
...9l...=> ...9_l...
...9U...=> ...9_u...
...UUl...=>...u_ul...

Ambos Buy24Beerse buy24beersse tornam buy_24_beers.
MacDonaldAndObriantorna-se mac_donald_and_obrian.
MACDonaldAndOBriantorna-se mac_donald_and_o_brian.


6
" MACDonaldAndOBriantorna-se mac_donald_and_o_brian" - por quê?
precisa saber é o seguinte

2
@ Qwertiy Porque eu pensei que esses nomes seriam divertidos. A menos que você esteja perguntando sobre a regra, que é coberta por ...UUl...=> ...u_ul....
CJ Dennis


@DigitalTrauma Surpreendentemente perto da minha pergunta original, mas sem as queixas de ser duas perguntas em uma e sem votos negativos! A maior diferença está no tratamento de cadeias ALLCAPS. Procurei se a pergunta já havia sido feita antes, mas não a encontrei.
CJ Dennis

1
@ggorlen o ...indica que está no meio de uma string.
CJ Dennis

Respostas:


7

Retina , 61 37 bytes

r1>`[A-Z]?[a-z]+|[A-Z]+|\d+
_$&
T`L`l

Experimente online! (Ligeiramente modificado para executar um conjunto de testes completo.)

Explicação

Em vez de encontrar limites de palavras para inserir sublinhados, simplesmente combinamos cada palavra e adicionamos um a _. A correspondência de palavras da esquerda é um pouco irritante por causa da UUlregra, mas, usando a correspondência da direita para a esquerda do .NET, podemos facilmente corresponder as palavras com avidez. Para evitar a liderança _, usamos os limites da Retina.

r1>`[A-Z]?[a-z]+|[A-Z]+|\d+
_$&

A rativa o modo da direita para a esquerda, a 1>conta Retina para o processo de tudo, exceto o primeiro jogo (contagem da esquerda para a direita). Depois, há quatro tipos de "palavras": Ulll, lll, UUU, ddd. Eles são facilmente compatíveis com o padrão fornecido. A substituição apenas escreve um _seguido pela própria palavra.

T`L`l

Isso simplesmente transforma maiúsculas em minúsculas para concluir a transformação.


6

JavaScript (ES6), 79 bytes

s=>s.match(/[A-Z]+(?=[A-Z][a-z]|\d|$)|[A-Z]?[a-z]+|\d+/g).join`_`.toLowerCase()

3

JavaScript (ES6), 89 bytes

s=>s.replace(/\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z])/g,"$&_").toL‌​owerCase()

2

Powershell, 77 bytes

Baseado na resposta de Neil .

$args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_'|% *wer

Script de teste com menos golfe:

$f = {

$args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_'|% toLower

}

@(
    ,("Buy24Beers", "buy_24_beers")
    ,("buy24beers", "buy_24_beers")
    ,("MacDonaldAndObrian", "mac_donald_and_obrian")
    ,("MACDonaldAndOBrian", "mac_donald_and_o_brian")
    ,("BigD", "big_d")
) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-ceq$expected): $result"
}

Resultado:

True: buy_24_beers
True: buy_24_beers
True: mac_donald_and_obrian
True: mac_donald_and_o_brian
True: big_d


1

PowerShell, 68 92 bytes

Excluídos brevemente, +24 bytes por usar o RegEx errado.

($args-creplace'\d(?=\D)|\D(?=\d)|[a-z](?=[A-Z])|.(?=[A-Z][a-z])','$&_').Trim('_').ToLower()

Experimente online!

Basicamente, o mesmo que as soluções JavaScript.


Não funciona com buy24beerse MACDonaldAndOBrian. Desculpe.
Mazzy

1
@mazzy corrigido, obrigado.
Gabriel Mills

0

Fator, 140 bytes

[ R/ [a-z][A-Z][a-z]/ [ dup from>> swap dup to>> swap seq>> subseq R/ [A-Z][a-z]/ [ "_" prepend ] re-replace-with ] re-replace-with >lower ]

Ungolfed:

: slice>subseq ( slice -- subseq )
dup from>> swap dup to>> swap seq>> subseq ;

: camel-case>snake-case ( string -- string' )
    R/ [a-z][A-Z][a-z]/ [
        slice>subseq R/ [A-Z][a-z]/
        [ "_" prepend ] re-replace-with
    ] re-replace-with >lower ;

0

Lua , 135 bytes

function snake(s)return s:gsub('%f[^%l]%u','_%1'):gsub('%f[^%a]%d','_%1'):gsub('%f[^%d]%a','_%1'):gsub('(%u)(%u%l)','%1_%2'):lower()end

Experimente online!

Esta solução se beneficia da notação abreviada de Lua para as classes de caracteres de C (minúscula %l, maiúscula %u, alfabética %a, dígito %d), notação de fronteira ( %f[]) e de toda a correspondência sendo adicionada como a primeira captura implícita na ausência de outras capturas.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.