Conversão de Convenção de Codificação

22

Nesse Coding Golf, você deve converter uma convenção de codificação com TitleCase em lower_case_with_underscores. E vice versa!

Especificação

Mude a caixa da seguinte maneira:

  • Se o caractere sublinhado for um delimitador, altere a caixa para maiúsculas e minúsculas sem delimitador.
  • Se houver várias palavras sem delimitador, altere a caixa para minúscula e adicione um caractere sublinhado como delimitador.
  • No caso de apenas uma palavra (ou um caractere): altere a caixa para maiúsculas e minúsculas se a palavra começar com minúsculas; altere a caixa para minúscula se a palavra começar com maiúscula.

Caracteres permitidos:

  • A a Z
  • A a Z
  • sublinhado ( _).

A entrada com palavras maiúsculas e minúsculas não é permitida. Exemplos de casos não permitidos:

  • Coding_Convention_Conversion
  • a_BC

Casos de exemplo

Input                        | Expected Output
===========================================================
CodingConventionConversion   | coding_convention_conversion
coding_convention_conversion | CodingConventionConversion
abc                          | Abc
Abc                          | abc
ABC                          | a_b_c
a_b_c                        | ABC
a                            | A
A                            | a

Regras

  • É permitido usar ToUpper, ToLowere ToTitleCasefunções.
  • É permitido o uso de expressões regulares.
  • : o menor código em bytes vence!
Dariusz Woźniak
fonte
Está usando uma ToTitleCasefunção bem? Você não especificou, então eu presumo que está tudo bem.
Justin
@ Justin: Boa pergunta, de fato. Vamos torná-lo mais divertido e não permitir a função ToTitleCase :)
Dariusz Woźniak
Darn ... minha solução depende dele
Justin
1
@ Justin: Ok - eu não o especifiquei no começo, então nesse caso - vamos permitir assim mesmo.
Dariusz Woźniak 26/01

Respostas:

4

Pitão, 25 bytes 29 33 35 40

Guardado 2 bytes graças a @Dennis

Guardado 4 bytes graças a @FryAmTheEggman

?rIz0smrd4cz\_tsXzrG1*\_G

Experimente online

Downgoat
fonte
Seu link precisa ser atualizado.
Isaacg
Quando tento colocar "abc" como entrada, ele produz "bc" como saída. Erro? :)
Dariusz Woźniak
Para corrigir o que @ DariuszWoźniak notou, você pode alterar sua condição de /z\_para rIz0. Eu também acredito que eu encontrei uma alternativa do mesmo comprimento para o programa sublinhados acrescentando: tsXzrG1_Mcj\_G2, talvez golf alguém possa mais ...
FryAmTheEggman
Ah, encontrei:tsXzrG1*\_G
FryAmTheEggman 26/01
8

Jolf, 35 bytes

Economiza 1 byte graças a @ Cᴏɴᴏʀ O'Bʀɪᴇɴ . Isso está codificado na ISO 8859-7.

? hI'_ΜGI'_dpyH0pxRGIL0"(?=[A-Z])'_

Woohoo meu primeiro programa Jolf!

Explicação

   // I = input
? hI'_                              // If input contains _
       GI'_                          // Split on _
      Μ    d                         // Loop, then join
            pyH0                     // Make the first character uppercase
                                    // ELSE...
                  RGIL0"(?=[A-Z])    // Split *after* all uppercase chars
                                 '_  // join with _ 
                px                   //Make lowercase

Experimente online

Downgoat
fonte
Você pode usar a separação de cadeias no final, para que ela se torne "(?=[A-Z])'_. A cadeia é fechada automaticamente.
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ oh, legal, obrigado!
Downgoat
7

Retina , 37

Obrigado a @ MartinBüttner por salvar 4 bytes!

^|[A-Z]
_$0
T`Ll`lL`_.
^_|_(?=[A-Z])

(Observe a nova linha à direita.)

Experimente online. Observe que isso inclui extra m`para configurar algumas linhas para tratar cada linha de entrada separadamente, para que todos os casos de teste possam ser executados de uma só vez. Isso não é um requisito da pergunta, portanto, eles não são contados na pontuação.

  • As linhas 1 e 2 são inseridas _no início da entrada ou antes das letras maiúsculas. Todas as palavras agora são _separadas, independentemente do caso.
  • A linha 3 alterna maiúsculas e minúsculas da primeira letra em cada palavra.
  • As linhas 4 e 5 são removidas _no início da entrada ou quando são seguidas por uma letra maiúscula.
Trauma Digital
fonte
Isso economiza quatro bytes: retina.tryitonline.net/…
Martin Ender
Além disso, você pode evitar a linha vazia à direita, omitindo a última ?=e substituindo esse estágio por $1(embora não afete a contagem de bytes).
Martin Ender
@ Martin Muito bom - obrigado!
Digital Trauma
5

GNU Sed, 46

Obrigado a @TobySpeight por salvar 2 bytes!

A pontuação inclui +1 na opção -E(ou -r) para sed.

s/(^|_)([a-z])/\u\2/g
t
s/[A-Z]/_\l&/g
s/^_//

Experimente online.

Bastante simples sed:

  • A linha 1 substitui o início da linha ou _, seguido por uma letra minúscula pela maiúscula dessa letra. O gsinalizador para sexecutar essa substituição para cada instância encontrada
  • tpula para o :rótulo sem nome se houver alguma correspondência para a substituição acima. Este rótulo está implicitamente no final.
  • Caso contrário, todas as letras maiúsculas serão substituídas _pela minúscula dessa letra
  • Isso deixa uma liderança _antes da primeira letra. s/^_//remove isso.
Trauma Digital
fonte
1
@ Toby Obrigado. -Efunciona no meu GNU sed 4.2.2 (Ubuntu 14.04.3), embora não esteja na página do manual. Eu li em algum lugar [citação necessário] que -Eé a opção Posix mais nova que será adicionada oficialmente ao GNU Sed em um lançamento mais recente, mas que já está lá não oficialmente. Independentemente disso, -rfaz a coisa certa se -Enão funcionar para você.
Digital Trauma
@Toby linhas 280-282 de sed / sed.c são /* Undocumented, for compatibility with BSD sed. */ case 'E': case 'r':.
Digital Trauma
@ Digital - Eu estava enganado; minha sed não aceitar -Ecomo sinônimo de -r. Eu não estava passando corretamente um programa mínimo, por exemplosed -E -e Q
Toby Speight
4

JavaScript (ES6), 87 bytes

s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())

Explicação

Dependendo de qual parte da regex corresponde, ela substitui a correspondência pela caixa oposta.

s.replace(
  /[A-Z]|(^|_)(.)/g,
  (c,_,l,i)=>
    l?
      (i?"_":"")+c.toLowerCase()
    :l.toUpperCase()
)

Teste

var solution = s=>s.replace(/[A-Z]|(^|_)(.)/g,(c,_,l,i)=>l?l.toUpperCase():(i?"_":"")+c.toLowerCase())
<input type="text" id="input" value="coding_convention_conversion" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

user81655
fonte
2

Ruby, 101 87 75 bytes

->s{s.gsub(/^.|[A-Z]/,'_\0').gsub(/_./,&:swapcase).gsub(/_(?=[A-Z])|^_/,'')}

Infelizmente, isso faz exatamente o mesmo que a solução Retina, pois esse método acabou sendo mais curto do que qualquer outra coisa que eu criei.

Justin
fonte
2

Python 3, 130 bytes

Tentativa rápida e suja usando regex para dividir nos limites. Força bruta: se alguém puder apresentar uma abordagem diferente, tenho certeza de que isso pode ser derrotado.

import re
lambda s:('_'.join(re.findall('[A-Z][a-z]*',s)).lower(),''.join([a[0].upper()+a[1:]for a in s.split('_')]))[s.islower()]
Ogaday
fonte
2

PHP 160 bytes

não é o mais curto, mas para ser completo aqui minha solução em PHP, $ s contém a string para converter:

trim(preg_replace_callback('/((^[a-z]|_[a-z])|([A-Z]))/',function($m){return empty($m[2])?'_'.strtolower($m[3]):strtoupper(str_replace('_','',$m[2]));},$s),'_')
Camelo
fonte
1
Bem-vindo à Programação de quebra-cabeças e troca de pilha de código de golfe. Muito bem por postar algo em um idioma que você sabia que não ia ganhar. Os desafios do código-golfe são principalmente em idiomas, portanto, usar um idioma não-golfe é bom. +1 d: D
wizzwizz4
1

Perl 6 ,  73 72 71   68 bytes

{.comb(/<:Lu><:Ll>*|<:Ll>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)} # 73
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x?/<:Lu>/)}  # 72
{/<:Lu>/??S:g/(^)?(<:Lu>)/{$0||'_'}$1.lc()/!!S:g/[^|_](<:Ll>)/$0.tc()/}   # 71
{.comb(/<:Lu><:Ll>*|<:L>+/).map({/<:Lu>/??.lc!!.tc}).join('_'x!/_/)}      # 68

Uso:

# give it a lexical name
my &code = {...}

for <CodingConventionConversion coding_convention_conversion abc Abc ABC a_b_c a A>
{ say .&code }
coding_convention_conversion
CodingConventionConversion
Abc
abc
a_b_c
ABC
A
a

Explicação:

{
  .comb( / <:Lu><:Ll>* | <:L>+ / ) # grab the "words" only
  .map({
      /<:Lu>/ # if the word has uppercase
    ??
      .lc     # lowercase the whole word
    !!
      .tc     # otherwise titlecase the word
   })
  .join(  # join the words
    '_'   # with '_'
    x     # repeated
    !/_/  # zero times if it had a _, otherwise once
  )
}

Você pode estar se perguntando por que usei as propriedades Unicode ( <:Lu>, <:Ll>) em vez de apenas uma classe de caracteres. No Perl 6, eles não são mais soletrados [a-z], são soletrados <[a..z]>1,6 vezes mais. Os colchetes [ … ]são usados ​​para o agrupamento de não captura, que foi escrito como (?: … )no Perl 5.

Brad Gilbert b2gills
fonte
1

Japonês, 40 bytes

UfV="%A" ?UrV@'_s!Y +Xv} :Ur"^.|_."_sJ u

Teste online!

Como funciona

           // Implicit: U = input string
UfV="%A"   // Set variable V to the string "\\A", and get all matches in U.
?          // If the list is not null:
UrV@     } //  Replace each match X and its index Y with this function:
'_s!Y +Xv  //   Return "_".slice(!Y) (1 for Y=0, 0 for anything else) + X.toLowerCase().
:          // Otherwise:
Ur"^.|_."  //  Replace the char at the beginning and each char following an underscore with:
_sJ u      //   The last char of the match (the letter) .toUpperCase().
ETHproductions
fonte
1

Perl 5, 42 bytes

40 bytes mais 2 por -p(obrigado, dev-null )

s/[A-Z]/_\l$&/g||s/(^|_)(.)/\u$2/g;s/_//
msh210
fonte
No Windows, usando perl e MINGW32, não recebo saída, o que estou perdendo?
ChatterOne
@ChatterOne Não sei o que é o MINGW32, mas funcionou bem para mim no Strawberry Perl. Use em -Evez de -e.
Msh210
1

𝔼𝕊𝕄𝕚𝕟 3, 15 caracteres / 32 bytes (não competitivo)

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï

Try it here (Firefox only).

A v3 foi lançada após esse desafio, com várias correções de bugs e atualizações da biblioteca.

Explicação

Este é apenas um mashup de builtins.

⟮ѨDZï⟯≠ï?Ⅰ:ѨȎѨƎï // implicit: ï=input
⟮ѨDZï⟯≠ï?        // check if ï is NOT in snake_case
       Ⅰ       // if so, then convert to snake_case
        :ѨȎѨƎï // otherwise, convert to camelCase and make the first letter UPPERCASE
Mama Fun Roll
fonte
1

Python 3 , 86 bytes

lambda s,u='_':''.join([u[i>u:]+i.lower()for i in(s<u)*s]or[u]+s.title().split(u))[1:]

Experimente online!

Também funciona em Python 2 .

Fazendo uso do fato conveniente de que o valor ascii para _(95) está correto entre os das letras maiúsculas (65-90) e minúsculas (97-122), o que permite comparações fáceis de cadeias.

Jitse
fonte
1

Quarto (gforth) , 129 bytes

: f bounds dup c@ 32 xor emit 1+ ?do i c@ '_ < if ." _"i c@ 32 + emit then i c@ '_ > if i 1- c@ '_ = 32 * i c@ + emit then loop ;

Experimente online!

Código Explicação

: f              \ start a new word definition
  bounds         \ convert string address and length to beginning and ending address
  dup c@         \ get the first character
  32 xor emit    \ convert to the opposite case and output
  1+             \ add 1 to beginning of string (skip starting char)
  ?do            \ begin counted loop over string character addresses
    i c@ '_ <    \ check if char is uppercase 
    if           \ if it is:
      ." _"      \ output underscore
      i c@       \ get current char
      32 + emit  \ convert to lowercase and output
    then         \ end if block
    i c@ '_ >    \ check if lowercase (not '_')
    if           \ if it is:
      i 1- c@    \ get the previous character
      '_ = 32 *  \ if it's an underscore, multiply by 32 (true = -1 in forth)
      i c@ +     \ add result to current char (make uppercase if previous was '_')
      emit       \ output resulting char
    then         \ end if block
  loop           \ end loop
;                \ end word definition
reffu
fonte